JuliusBrussee/caveman · error · Error
caveman agent: subagent maxCostUsd must be positive
Error message
caveman agent: subagent maxCostUsd must be positive
What it means
Thrown by the subagent tool factory when options.maxCostUsd is not a finite positive number. maxCostUsd is a hard spending ceiling for one subagent tool call; zero, negative, NaN, or Infinity values cannot bound spend. It is deliberately slightly looser than the integer checks: any finite positive number (including decimals) is accepted.
Source
Thrown at packages/agent/src/index.ts:178
* This child's wallet in tokens — the denomination sibling of `maxCostUsd`,
* used by a token-metered run. A token-metered run cannot fund a subagent
* that declares no token wallet.
*/
maxTokens?: number;
maxContextTokens?: number;
}): ToolDefinition {
const maxInputChars = options.maxInputChars ?? 32_768;
if (!Number.isSafeInteger(maxInputChars) || maxInputChars <= 0) {
throw new Error("caveman agent: subagent maxInputChars must be a positive integer");
}
const maxCalls = options.maxCalls ?? 1;
const maxCostUsd = options.maxCostUsd ?? 1;
const maxContextTokens = options.maxContextTokens ?? 128_000;
if (!Number.isSafeInteger(maxCalls) || maxCalls <= 0) {
throw new Error("caveman agent: subagent maxCalls must be a positive integer");
}
if (!Number.isFinite(maxCostUsd) || maxCostUsd <= 0) {
throw new Error("caveman agent: subagent maxCostUsd must be positive");
}
if (options.maxTokens !== undefined &&
(!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0)) {
throw new Error("caveman agent: subagent maxTokens must be a positive integer");
}
if (!Number.isSafeInteger(maxContextTokens) || maxContextTokens <= 0) {
throw new Error("caveman agent: subagent maxContextTokens must be a positive integer");
}
return tool({
name: options.name,
description: options.description,
input: schema.object({ task: schema.string() }),
effect: "read",
result: "auto",
...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
runtime: {
kind: "subagent",
definition: options.agent,View on GitHub (pinned to 27d5a3981a)
Solutions
- Pass a finite positive dollar amount, e.g. maxCostUsd: 2.5
- Validate config-sourced values before the call: Number.isFinite(v) && v > 0 ? v : 1
- If you intended 'no limit', pick the largest ceiling you actually accept — the library requires a positive finite bound
- Omit maxCostUsd entirely to use the default of 1 USD
Example fix
// before
subagentTool({ agent, name: "worker", maxCostUsd: Number(cfg.maxCost) }); // Number("") === 0 -> NaN/0
// after
const cost = Number(cfg.maxCost);
subagentTool({
agent,
name: "worker",
maxCostUsd: Number.isFinite(cost) && cost > 0 ? cost : 1,
}); Defensive patterns
Strategy: validation
Validate before calling
const maxCostUsd = Number(cfg.maxCost);
if (!Number.isFinite(maxCostUsd) || maxCostUsd <= 0) {
throw new Error(`maxCostUsd must be a finite positive dollar amount, got ${JSON.stringify(cfg.maxCost)}`);
} Type guard
const isPositiveFinite = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v) && v > 0;
Try / catch
try {
subagentTool({ agent, name: "worker", maxCostUsd });
} catch (e) {
if (e instanceof Error && e.message.includes("maxCostUsd")) { /* re-prompt operator for budget */ }
throw e;
} Prevention
- Document the unit (USD) next to every maxCostUsd config field
- Reject empty config values before Number() — Number("") is 0 and Number("abc") is NaN
- Remember 0 is never valid: this library has no unlimited mode
When it happens
Trigger: Passing maxCostUsd: 0 (a common mistake meaning 'no budget'), a negative number, NaN (e.g. from parsing a non-numeric env var), or Infinity. The default is 1 (USD); omission is fine.
Common situations: Wiring cost caps from user config where an empty string parses to NaN, using 0 to try to disable the cap, or misreading the unit (it is dollars, not cents) and passing 0.01-equivalent values like 1 when meaning 100.
Related errors
- caveman agent: subagent maxInputChars must be a positive int
- caveman agent: subagent maxCalls must be a positive integer
- caveman agent: subagent maxTokens must be a positive integer
- caveman agent: subagent maxContextTokens must be a positive
- cave_breaker_threshold_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/6f45acbc983b4d23.
Report an issue: GitHub.