← Back to PRs

#6143: fix(agents): handle AbortError from activeSession.abort() on timeout

by Glucksberg open 2026-02-01 09:58 View on GitHub →
agents size: XS experienced-contributor
## Summary Replace `void activeSession.abort()` with `activeSession.abort().catch(() => {})` to prevent unhandled promise rejection when in-flight HTTP requests are cancelled during embedded run timeout. ## Problem The gateway crashes with an unhandled promise rejection when an embedded agent run times out: ``` 02:29:59 [agent/embedded] embedded run timeout: runId=... timeoutMs=600000 02:29:59 [clawdbot] Unhandled promise rejection: AbortError: This operation was aborted at node:internal/deps/undici/undici:14902:13 ``` ## Root Cause In `agents/pi-embedded-runner/run/attempt.ts`, the `abortRun` function calls: ```javascript void activeSession.abort(); ``` When the timeout fires: 1. `runAbortController.abort()` is called and properly caught 2. `activeSession.abort()` cancels in-flight fetch requests 3. Those requests reject with `AbortError` 4. Since the promise is discarded with `void`, the rejection is unhandled 5. The unhandled rejection handler crashes the process ## Fix ```diff - void activeSession.abort(); + // Catch AbortError from in-flight requests - expected during timeout aborts + activeSession.abort().catch(() => {}); ``` The AbortError from undici's fetch is expected during timeout aborts and should not crash the gateway process. Fixes #5865 <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR updates the embedded runner timeout abort path in `src/agents/pi-embedded-runner/run/attempt.ts` so that `activeSession.abort()` no longer risks surfacing as an unhandled promise rejection when in-flight HTTP requests are canceled. The change replaces the prior fire-and-forget `void activeSession.abort()` call with `activeSession.abort().catch(() => {})`, aiming to prevent gateway crashes from undici `AbortError` during timeouts. The overall approach fits the existing abort/timeout flow in `runEmbeddedAttempt`: `runAbortController.abort()` is still the primary cancellation signal for local work, while `activeSession.abort()` is used to stop the session’s in-flight work (including network requests) when the run is terminated. <h3>Confidence Score: 4/5</h3> - This PR is likely safe to merge and should reduce crash risk on embedded run timeouts. - The change is narrowly scoped to the timeout abort path and addresses a clear unhandled-rejection failure mode; main risk is that the blanket catch could hide unexpected abort() failures, which is diagnosability rather than correctness for the normal case. - src/agents/pi-embedded-runner/run/attempt.ts <!-- greptile_other_comments_section --> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs