fix(providers/codex): remove stale attemptController.abort() that crashes after SDK cleanup#1739
Conversation
…shes after SDK cleanup (coleam00#1735) The codex-sdk's own finally calls child.removeAllListeners() + child.kill() before Archon's retry-loop finally runs. The subsequent attemptController.abort() fires Node's internal spawn-signal abort listener on the now-listenerless child, surfacing an uncaught AbortError that bypasses try/catch. The per-attempt AbortController is short-lived and goes out of scope at iteration end — no explicit abort() cleanup is needed. Caller signal cancellation is unaffected (removed via removeEventListener in the same finally block). Closes coleam00#1735
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR fixes a race condition in the Codex provider's retry loop where calling ChangesAbort cleanup race fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
Closes #1735
The fix in #1371 added
attemptController.abort()in the retry loop'sfinallyblock. By the time this runs, the codex-sdk's own finally has already calledchild.removeAllListeners()+child.kill(). The subsequentabort()fires Node's internal spawn-signal abort listener on the now-listenerless child, emitting an uncaughtAbortErrorthat bypasses any surrounding try/catch.100% reproducible — crashes the workflow ~9-15s into the first codex node.
Fix
Remove
attemptController.abort()from the finally block. The per-attemptAbortControlleris short-lived and goes out of scope at iteration end — no explicit cleanup needed. Caller signal cancellation is unaffected (removeEventListenerfor the caller's abort listener is retained in the same finally block).Changes
packages/providers/src/codex/provider.ts: RemoveattemptController.abort()from finally, add explanatory comment referencing bug(providers/codex):attemptController.abort()in retry finally crashes via codex-sdk's removeAllListeners (regression from #1371) #1735packages/providers/src/codex/provider.test.ts: Add regression test verifying successful attempts don't throw from stale abort cleanupValidation
bun test packages/providers/src/codex/provider.test.ts— 59 pass, 0 failsuccessful attempt does not throw from stale abort cleanup (#1735)passesSummary by CodeRabbit