fix(webhooks): run inactive deployment-version cleanup inline on deploy#5250
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview At the end of the The deferred Reviewed by Cursor Bugbot for commit 4508552. Configure here. |
Greptile SummaryThis PR moves inactive deployment cleanup into the active deployment sync path. The main changes are:
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (2): Last reviewed commit: "fix(webhooks): run inactive deployment-v..." | Re-trigger Greptile |
6998516 to
f75e0e0
Compare
When a deploy activates a new version, superseded versions' webhooks are removed by a separate, best-effort CLEANUP_INACTIVE outbox event. When that event is lost/dead-letters, old-version webhooks linger as is_active orphans that fetchActiveWebhooks skips (version mismatch), so they silently stop polling (~515 webhooks across ~130 workflows in prod). Run the existing cleanupInactiveDeploymentVersions synchronously in the SYNC_ACTIVE handler, right after the active version's webhooks/schedules are registered, falling back to the deferred outbox event only if the inline pass throws. This reuses the existing guarded cleanup, which re-checks each version is still inactive before tearing anything down (so it never touches the active version) and runs strictly after registration (so a teardown failure can't block it).
f75e0e0 to
4508552
Compare
|
@greptile review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 4508552. Configure here.
Summary
CLEANUP_INACTIVEoutbox event. When that event is lost / dead-letters silently, old-version webhooks linger asis_active=trueorphans thatfetchActiveWebhooksskips (deployment-version mismatch) — so they silently stop polling. In prod this stranded ~515 webhooks across ~130 workflows.cleanupInactiveDeploymentVersionssynchronously in theSYNC_ACTIVEhandler, right after the active version's webhooks/schedules are registered — falling back to the deferred outbox event only if the inline pass throws.isDeploymentVersionActive) before tearing anything down, and re-enqueues side-effects if a version became active — so it can never touch the active version.Why this layer (addressing the first review round)
An earlier revision folded stale-webhook deletion into
saveTriggerWebhooksForDeploy. Review correctly flagged two problems with that approach, both avoided here:strictExternalCleanup: true, so tearing down a stale/missing external subscription before registration could abort the deploy and leave the active version unregistered. Here cleanup runs strictly after registration, and a failure is caught and deferred — it can never block registration.cleanupInactiveDeploymentVersionsre-checks active-ness before each delete (the existingshouldDeleteWebhookguard), so it's race-safe.Scope
Closes the leak going forward. Backfilling the ~515 already-stranded rows remains a separate ops pass (the "fully dead" subset needs external OAuth/polling subscriptions recreated via deploy side-effects).
Type of Change
Testing
tsc+ biome clean. Full webhooks suite green.cleanupInactiveDeploymentVersionsunchanged; the only new code is an inline-with-deferred-fallback wrapper. An isolated test would require brittle deep-mocking of the cleanup's internal db-query ordering and would assert little, so it was deliberately omitted rather than added as a checkbox.Checklist