can1357/oh-my-pi · warning · ToolAbortError

${message}

Error message

${message}

What it means

When a bash command terminates because the abort signal fired mid-execution, BashTool checks whether buffered output starts with "[Command cancelled]"; if so it surfaces that text verbatim as a ToolAbortError, otherwise it appends "[Command aborted]" to the captured output (or uses a bare "Command aborted" when there is no output). The abort variant is thrown when signal.aborted is true at that point.

Source

Thrown at packages/coding-agent/src/tools/bash.ts:1437

		if (result.cancelled) {
			// A cancelled result is either a timeout (the command's deadline fired)
			// or a user/system abort. Timeouts are handled by #buildCompletedResult
			// which returns a non-throwing error result with details.timedOut=true
			// so the renderer can show a warning border instead of error red.
			// Both interactive and non-interactive results carry an explicit
			// `timedOut` field from the executor/PTY layer.
			const isTimeout = result.timedOut === true;
			if (!isTimeout) {
				const out = normalizeResultOutput(result);
				// The local executor already prepends `[Command cancelled]`; PTY
				// output does not, so preserve one cancellation notice in either case.
				const message = out.startsWith("[Command cancelled]")
					? out
					: out
						? `${out}\n\n[Command aborted]`
						: "Command aborted";
				if (signal?.aborted) {
					throw new ToolAbortError(message);
				}
				throw new ToolError(message);
			}
		}
		return this.#buildCompletedResult(result, timeoutSec, {
			requestedTimeoutSec,
			notices: pendingNotices,
			wallTimeMs,
		});
	}
}

// =============================================================================
// TUI Renderer
// =============================================================================
export interface BashRenderArgs {
	command?: string;
	env?: Record<string, unknown>;

View on GitHub (pinned to 9690622007)

Solutions

  1. Treat ToolAbortError as expected cancellation and stop processing
  2. Do not parse the message text (it contains command output); branch on the error class instead
  3. If aborts are spurious, audit what triggers the AbortSignal (UI cancel, deadline, teardown)
  4. Re-run the command after the abort condition clears
  5. Persist partial output from the message if the command's progress matters

Example fix

// before
const out = await bash.execute(cmd, { signal }); // throws on cancel
console.log(out);
// after
try {
  const out = await bash.execute(cmd, { signal });
} catch (e) {
  if (e instanceof ToolAbortError) return cancelled; // don't parse message text
  throw e;
}
Defensive patterns

Strategy: try-catch

Type guard

function isToolAbort(e: unknown): e is ToolAbortError { return e instanceof ToolAbortError; }

Try / catch

try {
  await bash.execute(cmd, { signal });
} catch (e) {
  if (isToolAbort(e)) {
    // message embeds command output — do not parse it programmatically
    return cancelled();
  }
  throw e;
}

Prevention

When it happens

Trigger: AbortSignal fires while the command is finishing or has just exited; the buffered output does not begin with the "[Command cancelled]" marker, so the tool constructs a message from the captured output plus "[Command aborted]" and throws ToolAbortError with it.

Common situations: User cancels a tool call just as the command completes; agent framework aborts the turn while a command is running; shell output captured right before abort is included in the error text, which can confuse log parsing.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/bf1928ae8788b2bf. Report an issue: GitHub.