fix(execution): retry transient database failures during execution setup - #7681
Conversation
A dropped Postgres connection during workflow execution setup killed the run permanently. The first read in preprocessing is the workflow fetch; an ECONNRESET there surfaced as "Internal error while fetching workflow", and because background executions run with maxAttempts 1 there was no retry. Route the read-only setup operations through the existing withDatabaseReadRetry helper so a dropped connection is retried in place, before any effect exists. The retried operations are all reads, so the rate-limit token debit and the concurrency reservation are never re-entered. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYi7yz8qo98ziQWZmRpqb8
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Greptile SummaryThis PR makes workflow execution setup resilient to transient database connection failures by applying the existing bounded read-retry helper to read-only preprocessing and executor operations.
Confidence Score: 5/5The PR appears safe to merge; no outstanding correctness, security, or repository-rule issue was identified. The retries are bounded to transient failures around read-only setup operations, preserve parallel loading, and do not repeat rate-limit or concurrency mutations. The previous type-safety thread was manually resolved after waleedlatif1 explained that the
|
| Filename | Overview |
|---|---|
| apps/sim/lib/db/read-retry.ts | Adds an optional diagnostic label while preserving the existing bounded transient-read retry behavior. |
| apps/sim/lib/execution/preprocessing.ts | Wraps six read-only preprocessing operations in database retries without re-entering admission mutations. |
| apps/sim/lib/execution/preprocessing.test.ts | Covers exhausted workflow-fetch retries and replaces prior any assertions in a manually resolved thread. |
| apps/sim/lib/workflows/executor/execution-core.ts | Retries executor setup reads while retaining concurrent workflow-state and environment loading. |
| apps/sim/lib/workflows/executor/execution-core.test.ts | Uses an event-loop boundary to assert setup-load concurrency without relying on a fixed microtask count. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Execution request] --> B[Preprocessing]
B --> C[Retry read-only setup operations]
C --> D[Rate-limit and concurrency admission]
D --> E[Execution core]
E --> F[Retry workflow state and environment loads]
F --> G[Retry remaining setup reads]
G --> H[Run first workflow block]
C -. transient failure .-> C
F -. transient failure .-> F
G -. transient failure .-> G
Reviews (2): Last reviewed commit: "test(execution): type the logging-sessio..." | Re-trigger Greptile
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYi7yz8qo98ziQWZmRpqb8
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
ECONNRESETthere surfaced asInternal error while fetching workflow, and background executions run withmaxAttempts: 1, so there was no retry.withDatabaseReadRetryhelper (lib/db/read-retry.ts) instead of adding a second retry helper. Its classifier is the right one for reads — it excludes57014so a caller's own statement timeout still propagates.preprocessing.ts, 5 inexecution-core.ts(includinggetCustomBlockRowsForWorkspace, the first read after preprocessing returns).labeltowithDatabaseReadRetryso the retry log line names which read flapped, matching the existingwithTransactionRetryoption shape.Not wrapped, deliberately:
getHighestPrioritySubscriptionswallows its own errors (onError: 'return-null') and never rejects, so a wrapper there would be dead code.Type of Change
Testing
Tested manually.
bun run type-check,bun run lint, all 46check:audits, anddocs-manifest:checkpass. 1,900 tests acrosslib/execution,lib/db,lib/workflows/executor,lib/knowledge/connectorsandbackgroundpass.Each new assertion was verified able to fail: unwrapping the call site turns the retry test red, and forcing the two parallel setup loads sequential turns the concurrency test red.
Checklist
🤖 Generated with Claude Code
https://claude.ai/code/session_01BYi7yz8qo98ziQWZmRpqb8