denoland/deno · error · TypeError
Delay cannot be NaN
Error message
Delay cannot be NaN
What it means
The third check in `validateQueueDelay`: comparisons against NaN are false, so NaN slips past the `< 0` and `> max` tests and is caught explicitly with this dedicated message. `kv.enqueue(..., { delay: NaN })` therefore throws before the op runs.
Solutions
- Default missing values: `delay ?? 0`
- Validate with `Number.isFinite(delay)` before the enqueue
- Fix the upstream computation that produced the NaN
Example fix
// before
await kv.enqueue(job, { delay: opts.delayMs * factor }); // NaN when delayMs undefined
// after
const delay = Number.isFinite(opts.delayMs) ? opts.delayMs * factor : 0;
await kv.enqueue(job, { delay }); Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isFinite(delay)) {
throw new Error(`delay is not a finite number: ${delay}`);
}
await kv.enqueue(msg, { delay }); Type guard
const isFiniteNumber = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v);
Prevention
- Default optional delay config with `?? 0` before arithmetic
- Validate parsed user input with Number.isFinite, not truthiness
- Run arithmetic only on values proven numeric
When it happens
Trigger: `delay: undefined * 1000` (undefined config multiplied); `Number.parseInt('soon')`-style parse failures; arithmetic on missing option values such as `options.delayMs * multiplier` where `delayMs` is undefined.
Common situations: Optional config that arrives as undefined; parsing user-supplied delay input; computing a delay from a missing field on an object.
Related errors
- Delay cannot be greater than 30 days: received
- Delay must be >= 0: received
- Invalid backoffSchedule, interval at index
- Invalid backoffSchedule, max
- expireIn must be a non-negative integer: received
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/5accd80f38700bbf.
Report an issue: GitHub.
Appendix: source
Thrown at ext/kv/01_db.ts:76
async function openKv(path: string) {
const rid = await op_kv_database_open(path);
return new Kv(rid, kvSymbol);
}
const maxQueueDelay = 30 * 24 * 60 * 60 * 1000;
function validateQueueDelay(delay: number) {
if (delay < 0) {
throw new TypeError(`Delay must be >= 0: received ${delay}`);
}
if (delay > maxQueueDelay) {
throw new TypeError(
`Delay cannot be greater than 30 days: received ${delay}`,
);
}
if (NumberIsNaN(delay)) {
throw new TypeError("Delay cannot be NaN");
}
}
function validateExpireIn(expireIn: number | undefined) {
if (expireIn === undefined) return;
// Reject NaN, Infinity, fractional and negative values. A non-finite
// expireIn otherwise reaches the native layer and overflows when computing
// the absolute expiry, panicking the process.
if (!NumberIsInteger(expireIn) || expireIn < 0) {
throw new TypeError(
`expireIn must be a non-negative integer: received ${expireIn}`,
);
}
}
const maxQueueBackoffIntervals = 5;
const maxQueueBackoffInterval = 60 * 60 * 1000;
View on GitHub (pinned to 9ad36f7a2c)