{"record":{"id":"70dba8b911646029","repo":"can1357/oh-my-pi","slug":"annotated-command-aborted","errorCode":null,"errorMessage":"${annotated || \"Command aborted\"}","messagePattern":"\\$\\{annotated \\|\\| \"Command aborted\"\\}","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"warning","filePath":"packages/coding-agent/src/tools/bash.ts","lineNumber":658,"sourceCode":"\t * details.timedOut=true so the renderer can show a warning border. The\n\t * foreground and bridge callers plus the async job manager rely on these\n\t * throwing so cancellations surface as aborts and jobs are recorded as\n\t * failed. A definite non-zero exit is a completed command that failed;\n\t * #buildCompletedResult surfaces it as an error *result* (carrying\n\t * execution details) rather than a throw.\n\t */\n\t#throwIfUnfinished(\n\t\tresult: BashResult | BashInteractiveResult,\n\t\ttimeoutSec: number | undefined,\n\t\toutputText: string,\n\t): void {\n\t\tif (result.cancelled) {\n\t\t\t// Local executor output already carries a leading `[Command cancelled]`\n\t\t\t// notice from the sink; PTY/bridge output does not, so annotate only\n\t\t\t// the latter.\n\t\t\tconst out = normalizeResultOutput(result);\n\t\t\tconst annotated = out.startsWith(\"[Command cancelled]\") ? out : out ? `${out}\\n\\n[Command aborted]` : out;\n\t\t\tthrow new ToolError(annotated || \"Command aborted\");\n\t\t}\n\t\tif (result.timedOut === true) {\n\t\t\tconst out = normalizeResultOutput(result);\n\t\t\tconst message =\n\t\t\t\ttimeoutSec === undefined ? \"Command timed out\" : `Command timed out after ${timeoutSec} seconds`;\n\t\t\tthrow new ToolError(out ? `${out}\\n\\n[${message}]` : message);\n\t\t}\n\t\tif (result.exitCode === undefined) {\n\t\t\tthrow new ToolError(`${outputText}\\n\\nCommand failed: missing exit status`);\n\t\t}\n\t}\n\n\tasync #buildCompletedResult(\n\t\tresult: BashResult | BashInteractiveResult,\n\t\ttimeoutSec: number | undefined,\n\t\toptions: {\n\t\t\trequestedTimeoutSec?: number;\n\t\t\tnotices?: readonly string[];","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/bash.ts#L640-L676","documentation":"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.","triggerScenarios":"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.","commonSituations":"User presses escape/cancel while a long-running command streams; session shutdown mid-command; programmatic abort of the agent run while bash is executing.","solutions":["Rerun the command if the cancellation was accidental.","Break long commands into smaller steps or add progress-friendly flags so they finish before cancellation.","Handle ToolError with this message in agent loops by treating it as an intentional abort, not a command bug.","Avoid launching commands that will be superseded mid-run; plan the command list before executing."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Avoid commands that outlive their usefulness; keep tool calls short.","Design agent loops to treat aborted commands as intentional, not retriable failures.","Check for cancellation signals before launching long batches."],"tags":["bash","cancellation","abort"],"backgroundTag":"command-aborted","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}