can1357/oh-my-pi · warning · ToolAbortError
${latestText} || Eval cell aborted
Error message
${latestText} || Eval cell aborted What it means
While foreground-waiting on an auto-backgrounded eval cell, the tool races the job's completion against the wait budget and the abort signal. If the caller's AbortSignal fires (the agent turn was cancelled/aborted), waitResult.kind becomes "aborted": the job is cancelled and a ToolAbortError is thrown, using the latest streamed output text as the message, or this generic message when nothing was streamed yet.
Source
Thrown at packages/coding-agent/src/tools/eval.ts:604
// Suppress the completion delivery up front so a job finishing while we
// foreground-wait cannot also be injected by the delivery loop. Lifted
// via resumeDeliveries() if we end up backgrounding after all.
autoBgManager.acknowledgeDeliveries([jobId]);
const waitResult = await raceJobSettlement(
completion.promise,
autoBackgroundWaitMs,
signal,
ctx?.toolCall?.steeringSignal,
);
if (waitResult.kind === "completed") {
return waitResult.result;
}
if (waitResult.kind === "failed") {
throw waitResult.error;
}
if (waitResult.kind === "aborted") {
autoBgManager.cancel(jobId);
throw new ToolAbortError(latestText || "Eval cell aborted");
}
forwardUpdates = false;
autoBgManager.resumeDeliveries([jobId]);
// "steer": a queued user/peer message arrived mid-wait — background the
// cell (it keeps running) so the message injects promptly.
const steerNotice =
waitResult.kind === "steer"
? "Backgrounded early to handle an incoming message; the cell keeps running."
: undefined;
return this.#buildBackgroundStartResult(jobId, cells, languages, notice, latestText, latestDetails, steerNotice);
}
/**
* Tool result returned when a cell converts into a background job: the live
* output tail plus the background notice, with details carrying the running
* cell snapshot and the async job marker the transcript renderer keys on.
*/
#buildBackgroundStartResult(View on GitHub (pinned to 9690622007)
Solutions
- This is expected cancellation behavior — check that the abort was intentional (user interrupt vs. spurious signal).
- Re-issue the eval cell if the work was still needed; the job was cancelled via autoBgManager.cancel(jobId).
- Avoid passing short-lived signals to execute() for long cells, or run the cell with auto-background disabled to control cancellation semantics explicitly.
Example fix
// before: shared signal aborted by unrelated timeout await evalTool.execute(id, params, shortLivedSignal); // after: dedicated controller scoped to the cell const c = new AbortController(); const p = evalTool.execute(id, params, c.signal); // abort only when this cell should stop: c.abort()
Defensive patterns
Strategy: try-catch
Validate before calling
if (signal?.aborted) return; // don't start work that will be aborted
Type guard
function isAbort(e: unknown): e is ToolAbortError { return e instanceof ToolAbortError || (e instanceof Error && e.name === "ToolAbortError"); } Try / catch
try {
await evalTool.execute(id, params, signal);
} catch (e) {
if (isAbort(e)) {
// intentional cancellation; cleanup or resubmit if work still needed
return;
}
throw e;
} Prevention
- Scope AbortControllers to the specific eval call, not a shared request signal.
- For long cells, prefer background mode and poll job status instead of long foreground waits.
- Distinguish user interrupts from orchestrator timeouts before resubmitting the cell.
When it happens
Trigger: Calling EvalTool.execute with an AbortSignal and aborting it while a backgrounded cell is still running (raceJobSettlement returns aborted); happens on user interrupt, cancellation of the agent turn, or upstream deadline.
Common situations: Users pressing escape/interrupt while a long eval cell runs in the background; orchestrators cancelling tool calls on timeouts; agent loops that abort superseded tool calls.
Related errors
- Request was aborted
- Auth broker request aborted
- OAuth refresh ownership aborted by caller
- Request was aborted.
- AbortError
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/38a8bf0eaac13360.
Report an issue: GitHub.