JuliusBrussee/caveman · error
cave_run_deadline_invalid
cave_run_deadline_invalid
Error message
cave_run_deadline_invalid
What it means
Thrown at run start when RunOptions.deadlineMs is present but not a safe integer greater than zero. The deadline stops the run at the same between-call checkpoints as the budget; a fractional, zero, negative, or non-finite deadline is a malformed value and is rejected before execution rather than treated as 'no deadline'.
Source
Thrown at packages/agent/src/runtime.ts:1085
throw new Error("cave_subagent_concurrency_limit_invalid");
}
if (options.lockedBuild !== undefined && options.candidatePlan !== undefined) {
throw new Error("cave_execution_authorization_ambiguous");
}
// Budget shape is settled before anything else happens: an ambiguous or
// unbounded budget must fail at run() start, not after the first dollar.
// maxCostUsd and budget are two different contracts for the same money —
// one terminates with an error, the other returns a planned partial result —
// so carrying both would leave the run's own stop semantics undecided.
if (options.budget !== undefined && options.maxCostUsd !== undefined) {
throw new Error("cave_budget_conflicting_cap");
}
const budgetMeter = executionContext.budgetMeter ?? (options.budget === undefined
? undefined
: new BudgetMeter(normalizeRunBudget(options.budget)));
if (options.deadlineMs !== undefined &&
(!Number.isSafeInteger(options.deadlineMs) || options.deadlineMs <= 0)) {
throw new Error("cave_run_deadline_invalid");
}
if (options.maxSubagentDepth !== undefined &&
(!Number.isSafeInteger(options.maxSubagentDepth) || options.maxSubagentDepth <= 0 ||
options.maxSubagentDepth > ABSOLUTE_SUBAGENT_DEPTH_LIMIT)) {
throw new Error("cave_subagent_depth_limit_invalid");
}
const deadlineAt = executionContext.deadlineAt ?? (options.deadlineMs === undefined
? undefined
: performance.now() + options.deadlineMs);
// A controller with nothing to release would be a silent no-op at the
// checkpoint that expected it to matter.
if (options.budgetController !== undefined && budgetMeter === undefined) {
throw new Error("cave_budget_controller_without_budget");
}
const breakers = options.breakers === undefined
? undefined
: new BreakerState(normalizeRunBreakers(options.breakers, budgetMeter !== undefined));
const efficiencyPlan = options.lockedBuild?.selected_plan ?? options.candidatePlan;View on GitHub (pinned to 27d5a3981a)
Solutions
- Pass a positive integer number of milliseconds, e.g. deadlineMs: 60_000, or omit it for no deadline
- If the computed remaining time is already <= 0, skip starting the run rather than passing 0
- Round computed values: Math.max(1, Math.floor(remainingMs))
Example fix
// before
await agent.run(input, { deadlineMs: endAt - Date.now() }); // 0 or negative when overdue
// after
const remaining = endAt - Date.now();
if (remaining <= 0) throw new Error("deadline already passed");
await agent.run(input, { deadlineMs: Math.floor(remaining) }); Defensive patterns
Strategy: validation
Validate before calling
const remaining = endAt - Date.now();
const opts = Number.isSafeInteger(remaining) && remaining > 0
? { deadlineMs: remaining }
: {}; // skip the run if remaining <= 0 Type guard
const isValidDeadline = (v: unknown): v is number => typeof v === "number" && Number.isSafeInteger(v) && v > 0;
Prevention
- Floor computed deadlines and reject non-positive remainders before calling run
- Remember the unit is milliseconds
- Do not pass 0 hoping it means 'immediate stop' — it is invalid
When it happens
Trigger: Passing deadlineMs: 0, a negative number, a float like 1500.5, NaN, or Infinity. Note executionContext.deadlineAt can also carry an inherited deadline, but the option itself must still be a positive safe integer when supplied.
Common situations: Computing a deadline from a remaining-time calculation that has already hit zero; passing seconds instead of milliseconds as a float; reading an unset env/config value that becomes NaN.
Related errors
- caveman agent: run maxCostUsd must be positive
- cave_subagent_invocation_limit_invalid
- cave_subagent_depth_limit_invalid
- cave_budget_controller_without_budget
- cave_${field}_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/e5205ab37e2452e0.
Report an issue: GitHub.