JuliusBrussee/caveman · error
cave_subagent_unpriced_budget
cave_subagent_unpriced_budget
Error message
cave_subagent_unpriced_budget
What it means
When preparing a subagent budget reservation, the runtime computes a USD ceiling for the model/context/output combination. If the ceiling cannot be computed because the model has no price (ceilingUsd === undefined), the runtime marks all spend ledgers incomplete — preserving honest accounting — and throws this error rather than reserving an unknown amount.
Solutions
- Use a priced model for the subagent, or correct the provider/model id so it matches the catalog.
- Reduce requested outputTokens/contextWindow to a configuration the pricing catalog covers.
- Extend the pricing catalog with the model's per-token prices if you maintain it.
- Disable cost budgeting for this subagent (no meter/ledger) if unpriced execution is acceptable — noting spend evidence will be marked incomplete.
Example fix
// before
const sub = runtime.spawnSubagent({ model: 'anthropic/claude-preview-x' });
// after: priced, catalog-known model
const sub = runtime.spawnSubagent({ model: 'anthropic/claude-sonnet-4' }); Defensive patterns
Strategy: validation
Validate before calling
const ceilingUsd = priceCeiling(model.provider, model.id, model.contextWindow, outputTokens);
if (ceilingUsd === undefined) throw new Error('cannot reserve: model unpriced'); Type guard
const isPricedForReservation = (model, outputTokens) => priceCeiling(model.provider, model.id, model.contextWindow, outputTokens) !== undefined;
Try / catch
try {
await reserveBudget({ model, outputTokens, ledgers });
} catch (e) {
if (e.message === 'cave_subagent_unpriced_budget') {
switchToPricedModelOrDropBudget();
} else throw e;
} Prevention
- Only assign priced models to budgeted subagents.
- Confirm provider/id strings match catalog entries exactly.
- Check ceiling availability before opening new ledgers.
When it happens
Trigger: Invoking the subagent budget-reservation function (runtime.ts:4666) with a model whose catalog pricing lookup returns undefined for the given provider/id, contextWindow, and outputTokens combination.
Common situations: Subagent configured with an unpriced custom or preview model; provider string not matching catalog entries (e.g. 'openai' vs 'azure/openai'); outputTokens requested beyond priced tiers so no ceiling formula applies.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- cave_budget_denomination_unavailable
- cave_subagent_call_budget
- cave_subagent_cost_budget
- cave_subagent_wallet_denomination_unavailable
- cave_subagent_wallet_unavailable
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/11a7a1d03a55b7f4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/runtime.ts:4666
function reserveProviderSpend(
ledgers: readonly SpendLedger[],
model: Model<Api>,
requestedOutputTokens: number | undefined,
): SpendReservation[] {
if (ledgers.length === 0) return [];
const outputTokens = Math.min(
model.maxTokens,
requestedOutputTokens ?? model.maxTokens,
);
const ceilingUsd = catalogSearchCeiling(
`${model.provider}/${model.id}`,
model.contextWindow,
outputTokens,
);
if (ceilingUsd === undefined) {
markSpendIncomplete(ledgers);
throw new Error("cave_subagent_unpriced_budget");
}
for (const ledger of ledgers) {
if (ledger.incomplete) throw new Error("cave_subagent_spend_evidence_incomplete");
if (ledger.actualUsd + ledger.reservedUsd + ceilingUsd > ledger.limitUsd) {
throw new Error(ledger.exceededCode);
}
}
const reservations = ledgers.map((ledger) => ({
ledger,
ceilingUsd,
provider: model.provider,
model: model.id,
}));
for (const { ledger } of reservations) ledger.reservedUsd += ceilingUsd;
return reservations;
}
function settleProviderSpend(View on GitHub (pinned to 3ee70a1026)