can1357/oh-my-pi · warning · Error
bridge call ${JSON.stringify(name)} aborted: eval cell was i
Error message
bridge call ${JSON.stringify(name)} aborted: eval cell was interrupted What it means
The Python eval tool bridge runs agent session tools on behalf of code executing inside a Python kernel cell. `callSessionToolPromptOnAbort` first checks the entry's `abortRequested()` probe; if the eval cell has already been interrupted, it refuses to start a new session-tool call and throws this error immediately. This is a deliberate guard so a cancelled cell cannot kick off fresh side-effecting tool work while the kernel is unwinding.
Source
Thrown at packages/coding-agent/src/eval/py/tool-bridge.ts:78
* Python invokes this bridge with blocking `urllib` requests from worker threads
* (each `agent()` / `tool.*` call). Two different aborts meet here:
*
* - {@link PyToolBridgeEntry.signal} goes to the tool, so a turn cancel tears
* down delegated work — subagents included — instead of leaving it running
* past the cell.
* - {@link PyToolBridgeEntry.shieldedSignal} decides when we may stop waiting.
* It is deferred across a critical `agent()` phase, so a cancel landing
* mid-merge cannot return early and let the cell settle while an
* abort-insensitive cherry-pick is still rewriting the repo.
*
* Calls arriving after an abort are rejected before starting. Otherwise the
* usual path is that the tool observes its own abort and rejects; the race only
* matters for tools that ignore the signal, keeping the kernel unwinding
* promptly instead of being hard-killed.
*/
async function callSessionToolPromptOnAbort(name: string, args: unknown, entry: PyToolBridgeEntry): Promise<unknown> {
if (entry.abortRequested?.()) {
throw new Error(`bridge call ${JSON.stringify(name)} aborted: eval cell was interrupted`);
}
const call = callSessionTool(name, args, {
session: entry.toolSession,
signal: entry.signal,
emitStatus: entry.emitStatus,
});
const signal = entry.shieldedSignal ?? entry.signal;
if (!signal) return await call;
if (signal.aborted) {
void call.catch(() => {});
throw new Error(`bridge call ${JSON.stringify(name)} aborted: eval cell was interrupted`);
}
const { promise: aborted, reject } = Promise.withResolvers<never>();
const onAbort = () => reject(new Error(`bridge call ${JSON.stringify(name)} aborted: eval cell was interrupted`));
signal.addEventListener("abort", onAbort, { once: true });
try {
return await Promise.race([call, aborted]);
} finally {View on GitHub (pinned to 9690622007)
Solutions
- Check the abort/interrupt state in your eval code before invoking the bridged tool and bail out early.
- If the interruption was unintentional, re-run the eval cell without interrupting it.
- If a tool must run to completion regardless of cell abort, invoke it outside the aborted cell context (e.g. in a fresh cell or session-level call).
Example fix
// before: tool callback ignores cancellation state
const result = await callSessionToolPromptOnAbort(name, args, entry);
// after: check abort before starting work (the library now does this for you)
if (entry.abortRequested?.()) {
throw new Error(`bridge call ${JSON.stringify(name)} aborted: eval cell was interrupted`);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (entry.abortRequested?.()) {
// skip the tool call entirely — cell is being interrupted
return;
} Type guard
function isAbortError(err: unknown): boolean {
return err instanceof Error && err.message.includes("aborted: eval cell was interrupted");
} Try / catch
try {
result = await callSessionToolPromptOnAbort(name, args, entry);
} catch (err) {
if (err instanceof Error && err.message.includes("aborted: eval cell was interrupted")) {
return; // expected during cell interrupt — stop gracefully
}
throw err;
} Prevention
- Check abortRequested() before each bridged tool call in eval code.
- Keep tool calls short so interrupts land between calls.
- Treat this error as a normal interrupt signal, not a bug.
When it happens
Trigger: Python eval cell code calls a bridged session tool (via callSessionToolPromptOnAbort) after the cell's abort signal has already fired — i.e. the cell was interrupted and the tool callback still runs before noticing the cancellation.
Common situations: A user hits interrupt/escape while a cell is mid-run; a tool-call timeout cancels the cell but the bridge callback is invoked anyway; asynchronous Python code that captured the bridge continues after the interrupt.
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/edbc85ec0f70fa95.
Report an issue: GitHub.