{"record":{"id":"a01c3b88b6002d10","repo":"can1357/oh-my-pi","slug":"agent-blocked-turn-token-budget-exhausted-tu","errorCode":null,"errorMessage":"agent() blocked: turn token budget exhausted (${turnBudget.spent}/${turnBudget.total} output tokens). Raise or drop the +Nk! ceiling to continue.","messagePattern":"agent\\(\\) blocked: turn token budget exhausted \\((.+?)/(.+?) output tokens\\)\\. Raise or drop the \\+Nk! ceiling to continue\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/eval/agent-bridge.ts","lineNumber":128,"sourceCode":"function buildSubagentFailureMessage(agentName: string, result: SingleResult): string {\n\tconst abortReason = trimToUndefined(result.abortReason);\n\tif (result.aborted && abortReason) return abortReason;\n\treturn (\n\t\ttrimToUndefined(result.error) ??\n\t\ttrimToUndefined(result.stderr) ??\n\t\tabortReason ??\n\t\t`agent() subagent '${agentName}' failed.`\n\t);\n}\n\n/**\n * Run a single subagent on behalf of an eval cell's `agent()` call.\n */\nexport async function runEvalAgent(args: unknown, options: EvalAgentBridgeOptions): Promise<EvalAgentResult> {\n\tconst parsed = parseAgentArgs(args);\n\tconst turnBudget = options.session.getTurnBudget?.();\n\tif (turnBudget?.hard && turnBudget.total !== null && turnBudget.spent >= turnBudget.total) {\n\t\tthrow new ToolError(\n\t\t\t`agent() blocked: turn token budget exhausted (${turnBudget.spent}/${turnBudget.total} output tokens). Raise or drop the +Nk! ceiling to continue.`,\n\t\t);\n\t}\n\tconst isolation =\n\t\tObject.hasOwn(parsed, \"isolated\") || Object.hasOwn(parsed, \"apply\") || Object.hasOwn(parsed, \"merge\")\n\t\t\t? {\n\t\t\t\t\t...(parsed.isolated !== undefined ? { requested: parsed.isolated } : {}),\n\t\t\t\t\t...(parsed.merge === false ? { merge: \"patch\" as const } : {}),\n\t\t\t\t\t...(parsed.apply !== undefined ? { apply: parsed.apply } : {}),\n\t\t\t\t}\n\t\t\t: undefined;\n\n\ttry {\n\t\tconst execution = await withBridgeTimeoutPause(\n\t\t\toptions.emitStatus,\n\t\t\t() =>\n\t\t\t\trunStructuredSubagent({\n\t\t\t\t\tsession: options.session,","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/eval/agent-bridge.ts#L110-L146","documentation":"The eval session can impose a hard per-turn output-token ceiling (+Nk!). Before spawning a subagent, the bridge checks the turn budget and refuses agent() calls once spent tokens reach the total, so a runaway eval cannot exceed the cap. The message tells you to raise or remove the hard ceiling.","triggerScenarios":"Calling agent() in an eval when the session's hard turn budget is fully spent (spent >= total, total !== null) — e.g. after many prior tool calls or large outputs consumed the +Nk! allocation.","commonSituations":"Eval configured with a tight +10k! hard budget but the workflow needs subagents late in the turn; loops calling agent() repeatedly until the budget is drained; forgot the ! makes the cap hard.","solutions":["Raise the hard ceiling, e.g. +50k! instead of +10k!","Drop the ! to make the budget soft (advisory) if a hard cap isn't needed","Restructure the eval to use fewer/smaller agent() calls","Split the work across turns so each turn gets a fresh budget"],"exampleFix":"// before (tight hard ceiling drains before agent())\n// eval header: budget +10k!\nagent({ prompt: 'refactor module' })\n// after: raise or soften\n// eval header: budget +100k!  (or +100k for soft)\nagent({ prompt: 'refactor module' })","handlingStrategy":"validation","validationCode":"const tb = session.getTurnBudget?.();\nif (tb?.hard && tb.total !== null && tb.spent >= tb.total) console.warn('budget exhausted; raise +Nk! before agent()');","typeGuard":"null","tryCatchPattern":"try { await agent(args) } catch (e) { if (/turn token budget exhausted/.test(e.message)) { raiseBudgetAndRetry(); } else throw e }","preventionTips":["Size the +Nk! ceiling above expected subagent usage","Reserve budget: call agent() early in the turn","Avoid agent() inside unbounded loops","Use a soft budget (no !) when a hard cap is not required"],"tags":["token-budget","eval","subagent","rate-limit"],"backgroundTag":"token-budget-exhausted","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}