{"record":{"id":"de9882d06f54b2ef","repo":"JuliusBrussee/caveman","slug":"cave-slot-budget-exceeded","errorCode":null,"errorMessage":"cave_${slot}_budget_exceeded","messagePattern":"cave_(.+?)_budget_exceeded","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/runtime.ts","lineNumber":2572,"sourceCode":"  }\n  return ordered;\n}\n\nexport function enforceSemanticBudgets(\n  bill: Readonly<Record<string, number>>,\n  outputMaxTokens: number,\n  plan: CavePlan,\n): void {\n  const slots: Array<[keyof CavePlan[\"budgets\"], number]> = [\n    [\"instructions\", bill.instruction ?? 0],\n    [\"tools\", bill.tool_schema ?? 0],\n    [\"memory\", bill.memory ?? 0],\n    [\"history\", bill.history ?? 0],\n    [\"results_artifacts\", (bill.artifact ?? 0) + (bill.skill ?? 0) + (bill.tool_result ?? 0)],\n    [\"output\", outputMaxTokens],\n  ];\n  for (const [slot, used] of slots) {\n    if (used > plan.budgets[slot]) throw new Error(`cave_${slot}_budget_exceeded`);\n  }\n}\n\nexport function assembleSystemPrompt(\n  definition: AgentDefinition,\n  lowered: LoweredContext,\n  bodies: ReadonlyMap<string, Uint8Array> = lowered.bodies,\n): string {\n  const decoder = new TextDecoder();\n  const required = [\"agent.instructions\", ...definition.contexts.map((item) => item.id)];\n  const parts: string[] = [];\n  for (const id of required) {\n    const segment = lowered.ir.segments.find((item) => item.id === id);\n    if (!segment) throw new Error(`cave_context_segment_missing:${id}`);\n    const body = bodies.get(segment.bodyHandle);\n    if (!body) throw new Error(`cave_context_body_missing:${id}`);\n    const text = decoder.decode(body);\n    parts.push(id === \"agent.instructions\" ? text : `<cave-context id=${JSON.stringify(id)}>\\n${text}\\n</cave-context>`);","sourceCodeStart":2554,"sourceCodeEnd":2590,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/runtime.ts#L2554-L2590","documentation":"Thrown by enforceSemanticBudgets when any semantic slot — instructions, tools, memory, history, results_artifacts, output — exceeds its plan budget. Slots are computed from the context bill (byte-derived token counts, bytes/4) plus the clamped output max. It enforces per-category budgets on top of overall spend control.","triggerScenarios":"Calling the run with an efficiency plan whose budgets are smaller than the assembled context: e.g. huge tool schemas exceeding the tools slot, long conversation history exceeding history, artifacts+skill+tool_result bytes exceeding results_artifacts, or outputMaxTokens above the output budget.","commonSituations":"Registering many/large tools (tools schema slot blows up); letting conversation history grow unbounded; large tool results or skill bodies; plans generated for a smaller agent definition reused on a bigger one.","solutions":["Identify the slot from the error message (cave_instructions_budget_exceeded, cave_tools_budget_exceeded, ...) and compare the bill against plan.budgets[slot]","Raise that slot's budget in the efficiency plan to fit the assembled context","Shrink the offending slot: fewer/smaller tools, prune history, compact tool results via transforms","Regenerate the plan after changing the agent definition so budgets reflect reality"],"exampleFix":"// before\nconst plan = { budgets: { tools: 2000, ... } }; // tool schemas are 5k tokens\n\n// after\nconst plan = { budgets: { tools: 8192, ... } };\n// or register fewer tools","handlingStrategy":"validation","validationCode":"// Pre-flight: estimate each slot from the assembled bill and compare\nfunction slotsWithinBudget(bill: ContextBill, outputMax: number, plan: CavePlan): string[] {\n  const slots: Array<[keyof CavePlan[\"budgets\"], number]> = [\n    [\"instructions\", bill.instruction ?? 0],\n    [\"tools\", bill.tool_schema ?? 0],\n    [\"memory\", bill.memory ?? 0],\n    [\"history\", bill.history ?? 0],\n    [\"results_artifacts\", (bill.artifact ?? 0) + (bill.skill ?? 0) + (bill.tool_result ?? 0)],\n    [\"output\", outputMax],\n  ];\n  return slots.filter(([slot, used]) => used > plan.budgets[slot]).map(([slot]) => slot);\n}","typeGuard":"function budgetSlotExceeded(e: unknown): string | null {\n  if (!(e instanceof Error)) return null;\n  const m = /^cave_(\\w+)_budget_exceeded$/.exec(e.message);\n  return m ? m[1] : null;\n}","tryCatchPattern":"try {\n  await agent.run(input, { efficiencyPlan: plan });\n} catch (e) {\n  const slot = budgetSlotExceeded(e);\n  if (slot) { plan.budgets[slot] *= 2; /* or trim that context slot */ }\n  else throw e;\n}","preventionTips":["Track context bills per agent and size budgets with headroom","Prune tools and history growth before they exceed slots","Regenerate efficiency plans whenever the definition's context set changes"],"tags":["budget","context","efficiency-plan"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}