fix(data-imports): retry Langfuse resource-limit 422s as transient - #72022
Merged
Conversation
Langfuse's public API maps a ClickHouse resource limit (memory/timeout) to HTTP 422 with a "Request timed out" body; genuine request-validation failures return 400. Deep offset pagination on the traces endpoint can trip that resource limit, so a 422 is a transient upstream error. fetch_page only retried 429/5xx, so a 422 raised a fatal HTTPError and failed the whole sync instead of flowing through the existing backoff and resume checkpoint. Treat 422 as retryable alongside 429/5xx. Generated-By: PostHog Code Task-Id: 471e3fa7-0a2b-4575-8c79-dd153f17022f
Contributor
|
Hey @Gilbert09! 👋 It looks like your git author email on this PR isn't your
You can fix it for this repo with: git config user.email "you@posthog.com"Or set it globally with |
There was a problem hiding this comment.
Small, well-tested fix widening retry handling for a transient Langfuse 422 in the warehouse import connector; diff matches description, author owns this area with strong familiarity, no risky-territory concerns.
- Author wrote 100% of the modified lines and has 2 merged PRs in these paths (familiarity STRONG).
- 👍 on the PR from hex-security-app[bot].
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 6L, 1F substantive, 22L/2F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1b-small (22L, 2F, single-area, fix) |
| stamphog 2.0.0b3 | .stamphog/policy.yml @ 65f0ccb · reviewed head e5ff92b |
Gilbert09
enabled auto-merge (squash)
July 17, 2026 16:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Error tracking surfaced an uncaught
HTTPErrorfrom the data warehouse import pipeline, in the Langfuse source:Issue: 019f70df-ab1b-7ab1-830c-b70904cf4781. Raised in
fetch_pageatproducts/warehouse_sources/backend/temporal/data_imports/sources/langfuse/langfuse.pyviaraise_for_status(), reached fromget_rowswhile paginating the v1 traces endpoint.The 422 looks like a client error but isn't one here. Langfuse's public API maps a ClickHouse resource limit (memory limit / overcommit / query timeout) to HTTP 422 with a
{"error": "Request timed out"}body. Genuine request-validation failures return 400, not 422. The v1 traces endpoint uses offset-based pagination, and deep offset pages (with the full trace field groups joined) get progressively heavier, so ClickHouse eventually hits a resource/time limit and the request comes back as a 422.That makes it a transient upstream error, not a credentials/config problem and not a bug in how we build the request (the parameters are valid). But
fetch_pageonly retried429and5xx, so a 422 raised a fatalHTTPErrorand failed the whole sync instead of being retried.Changes
Treat a Langfuse
422as retryable, alongside429/5xx. It now raisesLangfuseRetryableErrorand flows through the existing tenacity backoff and the resume checkpoint, giving a load- or time-limited request a chance to recover instead of crashing the sync. This is safe because on the Langfuse public API a 422 is exclusively a ClickHouse resource/timeout error — validation errors come back as 400.I did not widen
NonRetryableErrors: this is a transient timeout, so per the pipeline's error-handling policy it stays retryable.How did you test this code?
Automated only (I'm an agent — no manual sync run). Added
test_resource_limit_422_is_retried_then_recoverstoTestGetRows: it queues a422followed by a valid page and asserts the rows come back andsession.getwas called twice, proving the 422 was retried rather than surfaced as a fatal error. It catches a regression where 422 handling is dropped and a transient Langfuse timeout again crashes the sync — no existing test exercised the retry-on-status path throughget_rows.Ran the Langfuse source suite locally:
Invoked the
/writing-testsskill while adding the test.Automatic notifications
🤖 Agent context
Autonomy: Fully autonomous
Triaged from an error-tracking webhook by Claude. I confirmed the issue in PostHog error tracking (single occurrence, one team), read the stack trace end to end into
fetch_page/get_rows, then traced the 422 into Langfuse's own source:withMiddlewaresreturns 422 only forClickHouseResourceError(typesMEMORY_LIMIT/OVERCOMMIT/TIMEOUT), while zod validation errors return 400. That's what pinned the decision to "transient, keep retryable" rather than adding it toNonRetryableErrors. I considered tuningpage_size, but smaller pages mean deeper offsets for the same data, which doesn't reduce the offset-pagination cost — so the scoped fix is to retry. Checked open PRs (including the maintainer's) for a duplicate; none addresses this.Created with PostHog Code