denoland/deno · error · TypeError

Invalid backoffSchedule, interval at index

Error message

Invalid backoffSchedule, interval at index ${i} is invalid

What it means

Each entry of `backoffSchedule` must satisfy `0 <= interval <= 60*60*1000` ms (one hour, `maxQueueBackoffInterval`) and must not be NaN. `validateBackoffSchedule` walks the array and names the first offending index in the message; the enqueue is rejected before any op runs.

Solutions

  1. Clamp each entry: `schedule.map((i) => Math.min(3_600_000, Math.max(0, Math.round(i))))`
  2. Verify millisecond units and drop/merge intervals above one hour
  3. Filter out non-finite entries before enqueueing

Example fix

// before
await kv.enqueue(job, { backoffSchedule: [1000, 5, 7200000] }); // seconds & 2h -> throws

// after
await kv.enqueue(job, { backoffSchedule: [1000, 5000, 3_600_000] }); // ms, <= 1h
Defensive patterns

Strategy: validation

Validate before calling

const MAX_MS = 60 * 60 * 1000;
const backoffSchedule = rawSchedule
  .filter((i) => Number.isFinite(i))
  .map((i) => Math.min(MAX_MS, Math.max(0, Math.round(i))));
await kv.enqueue(msg, { backoffSchedule });

Type guard

const isValidBackoffInterval = (v: unknown): v is number =>
  typeof v === "number" && Number.isFinite(v) && v >= 0 && v <= 60 * 60 * 1000;

Prevention

When it happens

Trigger: `backoffSchedule: [1000, -5000]`; `[1000, 7_200_000]` (2 hours exceeds the 1-hour cap); an entry computed as NaN from missing config or bad parsing.

Common situations: Unit mistakes (seconds used where ms is expected); long idle-retry ladders that exceed an hour per step; intervals derived from external config that can be absent.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/481f2a29c698a72b. Report an issue: GitHub.

Appendix: source

Thrown at ext/kv/01_db.ts:107

  }
}

const maxQueueBackoffIntervals = 5;
const maxQueueBackoffInterval = 60 * 60 * 1000;

function validateBackoffSchedule(backoffSchedule: number[]) {
  if (backoffSchedule.length > maxQueueBackoffIntervals) {
    throw new TypeError(
      `Invalid backoffSchedule, max ${maxQueueBackoffIntervals} intervals allowed`,
    );
  }
  for (let i = 0; i < backoffSchedule.length; ++i) {
    const interval = backoffSchedule[i];
    if (
      interval < 0 || interval > maxQueueBackoffInterval ||
      NumberIsNaN(interval)
    ) {
      throw new TypeError(
        `Invalid backoffSchedule, interval at index ${i} is invalid`,
      );
    }
  }
}

interface RawKvEntry {
  key: Deno.KvKey;
  value: RawValue;
  versionstamp: string;
}

type RawValue = {
  kind: "v8";
  value: Uint8Array;
} | {
  kind: "bytes";
  value: Uint8Array;

View on GitHub (pinned to 9ad36f7a2c)