fix(data-warehouse): pause CDC schedule on non-retryable errors - #71453
Merged
estefaniarabadan merged 3 commits intoJul 16, 2026
Conversation
A non-retryable CDC extraction error (bad credentials, SSL required, unreachable host, an unrecoverable decode/merge) fails identically on every scheduled run, but until now only missing-slot/publication errors paused the schedule. So a source with wrong credentials kept its schedule firing, re-running the same deterministic auth failure and flooding the Syncs tab with failed jobs. Pause the source's CDC extraction schedule for these non-retryable errors so it stops until the user fixes the root cause and re-enables CDC. The cdc_broken marker is deliberately not set: the slot is intact, so the source stays ineligible for the destructive Repair CDC re-sync. The schema's FAILED status and the friendly "then re-enable change data capture" message remain the recovery cue. Generated-By: PostHog Code Task-Id: 0b24bfc2-fe5b-49b9-a1cd-c9dcda8ab702
estefaniarabadan
force-pushed
the
posthog-code/cdc-pause-schedule-on-nonretryable
branch
from
July 16, 2026 12:13
757cb39 to
ad37ec5
Compare
estefaniarabadan
marked this pull request as ready for review
July 16, 2026 12:43
Contributor
|
Reviews (1): Last reviewed commit: "fix(data-warehouse): pause CDC schedule ..." | Re-trigger Greptile |
danielcarletti
approved these changes
Jul 16, 2026
estefaniarabadan
enabled auto-merge (squash)
July 16, 2026 13:09
Contributor
🤖 CI report
|
| File | Patch | Uncovered changed lines |
|---|---|---|
products/warehouse_sources/backend/temporal/data_imports/cdc/activities.py |
27.3% | 1194–1196, 1198, 1200–1203 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 29502833558 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
warehouse_sources |
███████████████████░ 96.3% |
241,243 / 250,509 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
…yable Generated-By: PostHog Code Task-Id: 8c2c4547-61f6-4e4a-8c52-5ad20db2fb05
2 tasks
estefaniarabadan
deleted the
posthog-code/cdc-pause-schedule-on-nonretryable
branch
July 16, 2026 14:17
2 tasks
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
When a CDC source hits a non-retryable extraction error, we classify it correctly and Temporal stops retrying the activity. But the source's CDC extraction schedule keeps firing on its normal cadence. Each fire re-runs the same deterministic failure, and because a run that fails before its first flush backfills a terminal FAILED job per schema, this floods the Syncs tab with failed jobs for a source that cannot succeed until a human intervenes.
The loudest case is a bad-credentials (
auth_failed) source: the schedule re-runs it constantly, generating a large share of all V3 CDC failures while the actual fix (correct the credentials) is entirely on the user's side.Before this change, only
slot_missing/slot_not_configured/publication_missingpaused the schedule (viamark_cdc_broken). Every other non-retryable category kept firing.Changes
In
CDCExtractActivity._handle_failure, non-retryable errors that are not slot/publication problems now pause the source's CDC extraction schedule.mark_cdc_broken(they persist thecdc_brokenmarker and are eligible for Repair CDC, which recreates the slot)._pause_cdc_extraction_schedulehelper. It pauses the schedule best-effort and deliberately does not setcdc_broken: the slot is intact, so the source must stay ineligible for the destructive Repair CDC re-sync. The schema's FAILED status and the existing "then re-enable change data capture" message stay the recovery cue.Note
Behavior change: a non-retryable CDC failure now pauses the source's extraction schedule. The user resumes by fixing the root cause and re-enabling CDC, which recreates an unpaused schedule (the same recovery the error message already points to). A genuinely transient failure would need a manual re-enable instead of self-healing on the next tick, but these categories are, by classification, not retryable, so that trade is worth stopping the churn.
Before:
flowchart TD F[Non-retryable CDC error] --> Q{Slot/publication missing?} Q -->|Yes| B[mark_cdc_broken: pause schedule + broken marker] Q -->|No| K[Fail schema only; schedule keeps re-firing] classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff; class B phBlue class K phRedAfter:
flowchart TD F[Non-retryable CDC error] --> Q{Slot/publication missing?} Q -->|Yes| B[mark_cdc_broken: pause schedule + broken marker] Q -->|No| P[Pause extraction schedule; no broken marker] classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; class B phBlue class P phYellowHow did you test this code?
Automated only. I am an agent and did no manual or production testing.
test_missing_slot_or_publication_marks_cdc_brokento assert the routing: anauth_failedfailure (non-retryable, slot intact) pauses the schedule and does not callmark_cdc_broken, while slot/publication failures still mark broken and do not pause. This is the regression guard: revert the new branch and the auth case fails._pause_cdc_extraction_schedule(it callssync_connect) in the other non-retryable activity tests so they stay off the network.hogli test .../cdc/tests/test_extract_activity.py: 67 passed, 1 failure (TestBackpressureGuard::test_run_skips_tick_without_touching_schemas_or_reader). That failure is pre-existing: it reproduces on clean master, fails only in the full-file run with "Database access not allowed", and passes in isolation. It is an ordering/DB-fixture artifact unrelated to this change.hogli test .../cdc/tests/test_errors.py: 20 passed.ruff checkandruff formatclean;hogli ci:preflightgreen.Automatic notifications
Docs update
No docs change. This is internal pipeline behavior and the in-product recovery message is unchanged.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Directed by @estefaniarabadan; written by Claude (PostHog Code) in Claude Code. The problem surfaced during a 24h V3 pipeline health review that used the
investigating-warehouse-sources-loadskill; the fix used the/writing-testsgate before touching tests.Decisions:
mark_cdc_brokenfor auth.cdc_brokenis specifically the "slot/publication is gone, Repair CDC eligible" gate (repair.py:_require_broken_evidencerecreates the slot and forces a full re-sync). Auth has a healthy slot, so a separate pause path was added that does not set the marker.slot_not_configuredcategory on the same lines. My branch composes with it: that category is handled bymark_cdc_broken, and the newelifcatches the rest.Created with PostHog Code