can1357/oh-my-pi · warning · ToolError

${annotated || "Command aborted"}

Error message

${annotated || "Command aborted"}

What it means

When a bash command result reports cancelled, BashTool throws a ToolError so the abort is surfaced as a tool failure rather than a silent success. Output already starting with '[Command cancelled]' (from the local executor sink) is used as-is; other output gets '[Command aborted]' appended; with no output the bare message 'Command aborted' is thrown.

Source

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

	 * details.timedOut=true so the renderer can show a warning border. The
	 * foreground and bridge callers plus the async job manager rely on these
	 * throwing so cancellations surface as aborts and jobs are recorded as
	 * failed. A definite non-zero exit is a completed command that failed;
	 * #buildCompletedResult surfaces it as an error *result* (carrying
	 * execution details) rather than a throw.
	 */
	#throwIfUnfinished(
		result: BashResult | BashInteractiveResult,
		timeoutSec: number | undefined,
		outputText: string,
	): void {
		if (result.cancelled) {
			// Local executor output already carries a leading `[Command cancelled]`
			// notice from the sink; PTY/bridge output does not, so annotate only
			// the latter.
			const out = normalizeResultOutput(result);
			const annotated = out.startsWith("[Command cancelled]") ? out : out ? `${out}\n\n[Command aborted]` : out;
			throw new ToolError(annotated || "Command aborted");
		}
		if (result.timedOut === true) {
			const out = normalizeResultOutput(result);
			const message =
				timeoutSec === undefined ? "Command timed out" : `Command timed out after ${timeoutSec} seconds`;
			throw new ToolError(out ? `${out}\n\n[${message}]` : message);
		}
		if (result.exitCode === undefined) {
			throw new ToolError(`${outputText}\n\nCommand failed: missing exit status`);
		}
	}

	async #buildCompletedResult(
		result: BashResult | BashInteractiveResult,
		timeoutSec: number | undefined,
		options: {
			requestedTimeoutSec?: number;
			notices?: readonly string[];

View on GitHub (pinned to 9690622007)

Solutions

  1. Rerun the command if the cancellation was accidental.
  2. Break long commands into smaller steps or add progress-friendly flags so they finish before cancellation.
  3. Handle ToolError with this message in agent loops by treating it as an intentional abort, not a command bug.
  4. Avoid launching commands that will be superseded mid-run; plan the command list before executing.
Defensive patterns

Strategy: try-catch

Try / catch

try { await bash.run(cmd, opts); } catch (e) { if (e instanceof ToolError && (e.message === 'Command aborted' || e.message.includes('[Command aborted]'))) { /* treat as user-initiated cancel; stop or replan */ } else throw e; }

Prevention

When it happens

Trigger: The executed command was aborted before completion: the user cancelled the tool call in the UI, an abort signal propagated to the process, or the executor (local or PTY/bridge) returned result.cancelled === true.

Common situations: User presses escape/cancel while a long-running command streams; session shutdown mid-command; programmatic abort of the agent run while bash is executing.

Related errors


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