JuliusBrussee/caveman · error

cave_${slot}_budget_exceeded

Error message

cave_${slot}_budget_exceeded

What it means

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.

Source

Thrown at packages/agent/src/runtime.ts:2572

  }
  return ordered;
}

export function enforceSemanticBudgets(
  bill: Readonly<Record<string, number>>,
  outputMaxTokens: number,
  plan: CavePlan,
): void {
  const slots: Array<[keyof CavePlan["budgets"], number]> = [
    ["instructions", bill.instruction ?? 0],
    ["tools", bill.tool_schema ?? 0],
    ["memory", bill.memory ?? 0],
    ["history", bill.history ?? 0],
    ["results_artifacts", (bill.artifact ?? 0) + (bill.skill ?? 0) + (bill.tool_result ?? 0)],
    ["output", outputMaxTokens],
  ];
  for (const [slot, used] of slots) {
    if (used > plan.budgets[slot]) throw new Error(`cave_${slot}_budget_exceeded`);
  }
}

export function assembleSystemPrompt(
  definition: AgentDefinition,
  lowered: LoweredContext,
  bodies: ReadonlyMap<string, Uint8Array> = lowered.bodies,
): string {
  const decoder = new TextDecoder();
  const required = ["agent.instructions", ...definition.contexts.map((item) => item.id)];
  const parts: string[] = [];
  for (const id of required) {
    const segment = lowered.ir.segments.find((item) => item.id === id);
    if (!segment) throw new Error(`cave_context_segment_missing:${id}`);
    const body = bodies.get(segment.bodyHandle);
    if (!body) throw new Error(`cave_context_body_missing:${id}`);
    const text = decoder.decode(body);
    parts.push(id === "agent.instructions" ? text : `<cave-context id=${JSON.stringify(id)}>\n${text}\n</cave-context>`);

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Identify the slot from the error message (cave_instructions_budget_exceeded, cave_tools_budget_exceeded, ...) and compare the bill against plan.budgets[slot]
  2. Raise that slot's budget in the efficiency plan to fit the assembled context
  3. Shrink the offending slot: fewer/smaller tools, prune history, compact tool results via transforms
  4. Regenerate the plan after changing the agent definition so budgets reflect reality

Example fix

// before
const plan = { budgets: { tools: 2000, ... } }; // tool schemas are 5k tokens

// after
const plan = { budgets: { tools: 8192, ... } };
// or register fewer tools
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: estimate each slot from the assembled bill and compare
function slotsWithinBudget(bill: ContextBill, outputMax: number, plan: CavePlan): string[] {
  const slots: Array<[keyof CavePlan["budgets"], number]> = [
    ["instructions", bill.instruction ?? 0],
    ["tools", bill.tool_schema ?? 0],
    ["memory", bill.memory ?? 0],
    ["history", bill.history ?? 0],
    ["results_artifacts", (bill.artifact ?? 0) + (bill.skill ?? 0) + (bill.tool_result ?? 0)],
    ["output", outputMax],
  ];
  return slots.filter(([slot, used]) => used > plan.budgets[slot]).map(([slot]) => slot);
}

Type guard

function budgetSlotExceeded(e: unknown): string | null {
  if (!(e instanceof Error)) return null;
  const m = /^cave_(\w+)_budget_exceeded$/.exec(e.message);
  return m ? m[1] : null;
}

Try / catch

try {
  await agent.run(input, { efficiencyPlan: plan });
} catch (e) {
  const slot = budgetSlotExceeded(e);
  if (slot) { plan.budgets[slot] *= 2; /* or trim that context slot */ }
  else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/de9882d06f54b2ef. Report an issue: GitHub.