can1357/oh-my-pi · warning · ToolError
${out}\n\n[${message}]
Error message
${out}\n\n[${message}] What it means
When result.timedOut === true, BashTool throws a ToolError reporting the timeout. The message is 'Command timed out' or 'Command timed out after N seconds' (when the tool call specified a timeoutSec), and any captured output is prepended so the user sees what the command produced before it was killed.
Source
Thrown at packages/coding-agent/src/tools/bash.ts:664
*/
#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[];
terminalId?: string;
wallTimeMs?: number;
} = {},
): Promise<AgentToolResult<BashToolDetails>> {
const exitCode = result.exitCode;
const failedExit = exitCode !== undefined && exitCode !== 0;View on GitHub (pinned to 9690622007)
Solutions
- Increase the timeoutSec parameter for legitimately long commands.
- Run long-lived processes in the background (nohup ... &, redirect logs) and poll them instead of blocking the tool call.
- Fix the command so it actually terminates — add its own timeouts, remove interactive prompts, pipe input.
- Disable pagers/interactive behavior with flags (e.g. --no-progress, CI=1, </dev/null) that commonly cause hangs.
Example fix
// before
await bash.run("npm install", {}); // hangs past default timeout
// after
await bash.run("npm install", { timeoutSec: 600 }); Defensive patterns
Strategy: try-catch
Try / catch
try { await bash.run(cmd, opts); } catch (e) { if (e instanceof ToolError && e.message.includes('Command timed out')) { /* raise timeoutSec, background the process, or fix the hang */ } else throw e; } Prevention
- Always set an explicit timeoutSec sized to the command's expected runtime.
- Background long-lived servers/watchers instead of blocking the tool call.
- Eliminate interactive stdin prompts (use </dev/null, CI env flags).
- Give network commands their own internal timeouts.
When it happens
Trigger: The bash tool call exceeded its allowed runtime: a timeoutSec was supplied in the tool arguments and the command ran longer than it, or a default timeout fired (timeoutSec undefined).
Common situations: Long-running installs, builds, watches, servers, or interactive prompts (commands waiting on stdin) that never exit; network operations hanging without timeouts of their own.
Related errors
- Command timed out after ${err.message.slice("timeout:".lengt
- Command timed out
- timed out: {command}
- AnthropicConnectionTimeoutError
- Kimi device flow timed out
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/17072c012a9e0cd9.
Report an issue: GitHub.