JuliusBrussee/caveman · error · MiddlewareError
invalid_deadline
invalid_deadline
Error message
invalid_deadline
What it means
MiddlewareError('invalid_deadline') is thrown by the MiddlewareRuntime constructor when options.deadlineMs or options.retrieveDeadlineMs is provided but is not a positive safe integer. These options define the millisecond budget for capability discovery and optimize/retrieve HTTP calls. The constructor validates them eagerly so bad deadline configuration fails at startup instead of mid-request.
Solutions
- Pass a positive safe integer, e.g. deadlineMs: 100
- Parse config values with Number.parseInt and validate > 0 before constructing the runtime
- Omit the option entirely to use the built-in 100ms default
Example fix
// before
new MiddlewareRuntime({ deadlineMs: process.env.DEADLINE }) // string
// after
const d = Number.parseInt(process.env.DEADLINE ?? '', 10);
new MiddlewareRuntime({ deadlineMs: Number.isSafeInteger(d) && d > 0 ? d : undefined }) Defensive patterns
Strategy: validation
Validate before calling
const isValidDeadline = (v) => v === undefined || (Number.isSafeInteger(v) && v > 0);
if (!isValidDeadline(deadlineMs) || !isValidDeadline(retrieveDeadlineMs)) throw new Error('deadlineMs/retrieveDeadlineMs must be positive integers'); Type guard
const isPositiveInt = (v: unknown): v is number => typeof v === 'number' && Number.isSafeInteger(v) && v > 0;
Try / catch
try { const rt = createMiddlewareRuntime({ deadlineMs }); } catch (e) { if (e instanceof MiddlewareError && e.code === 'invalid_deadline') { /* fall back to default deadlines */ } else throw e; } Prevention
- Parse numeric config with Number.parseInt and validate before construction
- Never assign timestamps (Date.now()) as durations
- Centralize runtime construction so deadlines are validated in one place
When it happens
Trigger: new MiddlewareRuntime({ deadlineMs: 0 }), a negative deadlineMs/retrieveDeadlineMs, a non-integer like 99.5, NaN/Infinity, or a value passed as a string that exceeds Number.isSafeInteger.
Common situations: Reading deadline values from env vars or config files without parsing to int; computing a deadline via division producing a float; copying a Date.now() timestamp in as a deadline instead of a duration.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- cave_mastra_max_steps_invalid
- caveman agent: context id is required
- caveman agent: memory recallBudget must be a non-negative…
- maxLoadedTools must be a positive integer
- maxLoadedTools must be at least the alwaysLoad tool count
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/7df96b8dac7c1271.
Report an issue: GitHub.
Appendix: source
Thrown at packages/sdk/typescript/src/middleware/runtime.ts:98
private readonly lifetime = new AbortController();
private readonly bindings = new WeakSet<RecoveryBinding>();
private readonly capsCache: { value: Capabilities | null } = { value: null };
private failures = 0;
private openUntil = 0;
private pending = 0;
private receiptsPending = 0;
private fetchesPending = 0;
private receiptFetchesPending = 0;
private receiptTail: Promise<void> = Promise.resolve();
private reported: CallReport | null = null;
constructor(options: RuntimeOptions = {}) {
const url = new URL(options.endpoint ?? 'http://127.0.0.1:8787');
const local = ['127.0.0.1','[::1]','localhost'].includes(url.hostname);
if (!['http:','https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash || (url.pathname !== '/' && url.pathname !== '')) throw new MiddlewareError('invalid_endpoint');
if (!local && (!options.allowRemoteContent || url.protocol !== 'https:')) throw new MiddlewareError('remote_content_not_enabled');
for (const value of [options.deadlineMs, options.retrieveDeadlineMs]) {
if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) throw new MiddlewareError('invalid_deadline');
}
this.endpoint = url.origin;
this.options = { ...options };
this.mode = options.mode ?? 'compress';
this.fetcher = options.fetch ?? globalThis.fetch;
}
/** Prime capability discovery during app startup, outside the first model call. */
async ready(signal?: AbortSignal): Promise<Capabilities> {
signal?.throwIfAborted();
if (this.mode === 'off') throw new MiddlewareError('off');
const value = validateCapabilities(await this.http('capabilities', undefined, this.options.deadlineMs ?? 100, signal));
this.capsCache.value = value;
return value;
}
/** Nonthrowing startup discovery, including strict mode. Caller cancellation
* still propagates. Sends no candidate content or provider request. */View on GitHub (pinned to 3ee70a1026)