can1357/oh-my-pi · error · ToolError
${failureMessage}${recoveryHint} (subagent failure: ${policy
Error message
${failureMessage}${recoveryHint} (subagent failure: ${policy.agentName} exited ${result.exitCode} or errored/aborted) What it means
When the spawned eval subagent exits non-zero, errors, or aborts, the bridge surfaces buildSubagentFailureMessage (tag-stripped) plus — for isolated subagents — a structured recovery hint, wrapped in a ToolError. It means the delegated agent() run itself failed, not the parent tool.
Source
Thrown at packages/coding-agent/src/eval/agent-bridge.ts:173
keepAlive: false,
// `maxRuntimeMs` is intentionally omitted: the executor then inherits
// `task.maxRuntimeMs`, matching the task tool. Pinning it to 0 here
// silently overrode the user's wall-clock cap for eval fan-outs.
shareEvalSession: false,
...(options.signal !== undefined ? { signal: options.signal } : {}),
...(options.emitStatus
? { onProgress: (progress: AgentProgress) => emitProgressStatus(options.emitStatus, progress) }
: {}),
}),
{ deferExternalAbort: true },
);
const { result, policy, mergeSummary, changesApplied, artifactsDir } = execution;
if (result.exitCode !== 0 || result.error || result.aborted) {
const failureMessage = buildSubagentFailureMessage(policy.agentName, result)
.replace(/<\/?system-notification>/g, "")
.trim();
const recoveryHint = policy.isIsolated ? await buildStructuredSubagentRecoveryHint(result, artifactsDir) : "";
throw new ToolError(`${failureMessage}${recoveryHint}`);
}
if (policy.isIsolated && changesApplied === false) {
const summary = mergeSummary.replace(/<\/?system-notification>/g, "").trim();
const recoveryHint = await buildStructuredSubagentRecoveryHint(result, artifactsDir);
throw new ToolError(
`agent() isolated apply failed for ${result.id}${summary ? `: ${summary}` : ""}${recoveryHint}`,
);
}
const structuredOutput = result.structuredOutput;
const structured = structuredOutput?.source !== undefined && structuredOutput.source !== "none";
if (structured && mergeSummary.includes("<system-notification>")) {
const recoveryHint = await buildStructuredSubagentRecoveryHint(result, artifactsDir);
throw new ToolError(
`agent() isolated nested patch apply failed for ${result.id}: ${mergeSummary.replace(/<\/?system-notification>/g, "").trim()}${recoveryHint}`,
);
}
View on GitHub (pinned to 9690622007)
Solutions
- Read failureMessage for the subagent's own error and the recovery hint for artifacts location
- Re-run with a smaller/simpler prompt to isolate the failure
- Check subagent logs/artifacts dir for the underlying stack trace
- Fix auth/network/model-availability issues indicated in the message
Example fix
// before: prompt causes subagent crash, no diagnosis
agent({ prompt: hugePrompt })
// after: inspect artifacts and retry with constrained prompt
try { await agent({ prompt }) } catch (e) { console.log(e.message /* includes artifactsDir hint */) } Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check environment the subagent needs
if (!(await $which('git'))) throw new Error('subagent requires git on PATH'); Type guard
function subagentFailed(r: { exitCode: number; error?: unknown; aborted?: boolean }): boolean { return r.exitCode !== 0 || !!r.error || r.aborted; } Try / catch
try { await agent(args) } catch (e) { const m = e.message; if (/subagent failure/.test(m)) { inspectArtifacts(m); retryWithSmallerPrompt(); } else throw e } Prevention
- Keep subagent prompts scoped so they finish within limits
- Verify API keys/model availability before eval runs
- Avoid aborting the parent mid-subagent
- Check artifacts dir from the recovery hint on any failure
When it happens
Trigger: agent() call where the subagent process returned exitCode !== 0, set result.error, or was aborted (result.aborted) — crash, OOM, model/API failure, user abort, or unhandled exception inside the subagent.
Common situations: Subagent hit an API rate limit or auth failure; prompt caused the subagent to exceed its own limits and abort; environment missing a binary the subagent invoked; eval infrastructure killed the process.
Related errors
- agent() blocked: turn token budget exhausted (${turnBudget.s
- agent() isolated apply failed for ${result.id}${summary ? `:
- agent() isolated nested patch apply failed for ${result.id}:
- ${error.message} (rethrown as ToolError from StructuredSubag
- cli_message(command, exit_code, stdout, stderr)
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/fdf08fad275cff2d.
Report an issue: GitHub.