JuliusBrussee/caveman · error
cave_${slot}_budget_exceeded
cave_${slot}_budget_exceeded
Error message
cave_${slot}_budget_exceeded What it means
Thrown by the budget-validation step of the Caveman agent runtime when a token bill for one prompt slot exceeds the allocation in the lowered plan (plan.budgets). The runtime splits the prompt into slots — memory, history, results_artifacts (artifact+skill+tool_result), and output — and enforces hard per-slot caps before assembling the request. It throws early with the slot name in the message so the caller knows which budget was blown.
Solutions
- Identify the slot named in the message (e.g. cave_history_budget_exceeded means history) and trim or compact that segment's content.
- Raise the corresponding budgets[slot] value in the plan/agent definition to a realistic ceiling.
- Enable or widen compaction/transform routes for the offending slot so content is reduced before budget validation.
- Check for runaway growth (unbounded tool_result accumulation) and cap tool output or drop old results.
Example fix
// before
plan.budgets = { memory: 1000, history: 2000, results_artifacts: 2000, output: 1000 };
// with a 3500-token history
// after
plan.budgets = { memory: 1000, history: 4000, results_artifacts: 2000, output: 1000 };
// or compact history before the run Defensive patterns
Strategy: validation
Validate before calling
const slots = { 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 Object.entries(slots)) {
if (used > plan.budgets[slot]) console.warn(`slot ${slot} over budget: ${used} > ${plan.budgets[slot]}`);
} Type guard
function withinBudget(used: number, budget: number | undefined): boolean { return typeof budget === "number" && used <= budget; } Try / catch
try {
await agent.run(input);
} catch (err) {
if (err instanceof Error && /^cave_[a-z_]+_budget_exceeded$/.test(err.message)) {
const slot = err.message.match(/^cave_([a-z_]+)_budget_exceeded$/)?.[1];
// compact that slot or raise plan.budgets[slot], then retry
} else throw err;
} Prevention
- Track per-slot token usage after each turn and compact proactively before caps are hit.
- Set budgets with headroom (e.g. 80% of the real limit you want enforced).
- Cap tool_result sizes at the tool boundary so artifacts never dominate the bill.
- Re-validate budgets whenever the agent definition or context sources change.
When it happens
Trigger: Calling the agent run path with a bill whose value for a slot (memory, history, artifact/skill/tool_result totals) exceeds plan.budgets[slot], or whose planned outputMaxTokens exceeds the output budget. Any single slot over its cap trips the check in the slot loop.
Common situations: Injecting an oversized memory blob or accumulated history without compaction; many tool results/artifacts accumulating in one turn; a plan configured with tight budgets while the context naturally grew; upgrading agents without revisiting budget allocations.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- cave_budget_conflicting_cap
- cave_budget_controller_without_budget
- cave_budget_denomination_unavailable
- cave_output_budget_exceeded
- budget is below CCR storage minimum
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/de9882d06f54b2ef.
Report an issue: GitHub.
Appendix: 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 3ee70a1026)