{"record":{"id":"7a2accdcba9429ac","repo":"denoland/deno","slug":"invalid-backoffschedule-max-maxqueuebackoffinte","errorCode":null,"errorMessage":"Invalid backoffSchedule, max ${maxQueueBackoffIntervals} intervals allowed","messagePattern":"Invalid backoffSchedule, max (.+?) intervals allowed","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/kv/01_db.ts","lineNumber":97,"sourceCode":"\nfunction validateExpireIn(expireIn: number | undefined) {\n  if (expireIn === undefined) return;\n  // Reject NaN, Infinity, fractional and negative values. A non-finite\n  // expireIn otherwise reaches the native layer and overflows when computing\n  // the absolute expiry, panicking the process.\n  if (!NumberIsInteger(expireIn) || expireIn < 0) {\n    throw new TypeError(\n      `expireIn must be a non-negative integer: received ${expireIn}`,\n    );\n  }\n}\n\nconst maxQueueBackoffIntervals = 5;\nconst maxQueueBackoffInterval = 60 * 60 * 1000;\n\nfunction validateBackoffSchedule(backoffSchedule: number[]) {\n  if (backoffSchedule.length > maxQueueBackoffIntervals) {\n    throw new TypeError(\n      `Invalid backoffSchedule, max ${maxQueueBackoffIntervals} intervals allowed`,\n    );\n  }\n  for (let i = 0; i < backoffSchedule.length; ++i) {\n    const interval = backoffSchedule[i];\n    if (\n      interval < 0 || interval > maxQueueBackoffInterval ||\n      NumberIsNaN(interval)\n    ) {\n      throw new TypeError(\n        `Invalid backoffSchedule, interval at index ${i} is invalid`,\n      );\n    }\n  }\n}\n\ninterface RawKvEntry {\n  key: Deno.KvKey;","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/kv/01_db.ts#L79-L115","documentation":"kv.enqueue accepts options.backoffSchedule, an array of retry intervals (ms) applied when a message handler fails. Deno limits it to at most 5 intervals (maxQueueBackoffIntervals); a longer array is rejected before the enqueue op runs.","triggerScenarios":"kv.enqueue(msg, { backoffSchedule: [100, 1000, 10000, 60000, 300000, 1800000] }) with six entries; generating the schedule programmatically (e.g. exponential backoff loop of 7 steps); merging retry policies from another system with more stages.","commonSituations":"Porting RabbitMQ/SQS retry ladders with many stages; auto-generated exponential schedules (2^n for n up to 10); combining default plus custom schedules via array spread/concat.","solutions":["Trim to at most 5 intervals: backoffSchedule.slice(0, 5).","After the last interval, use the message's dead-letter behavior (a non-retryable failure path) instead of more stages.","When generating, cap the loop at 5 iterations."],"exampleFix":"// before\nconst backoffSchedule = Array.from({ length: 8 }, (_, i) => 2 ** i * 100);\nawait kv.enqueue(job, { backoffSchedule });\n\n// after\nconst backoffSchedule = Array.from({ length: 5 }, (_, i) => 2 ** i * 100);\nawait kv.enqueue(job, { backoffSchedule });","handlingStrategy":"validation","validationCode":"const MAX_INTERVALS = 5;\nconst backoffSchedule = rawSchedule\n  .filter((i) => Number.isFinite(i) && i >= 0)\n  .slice(0, MAX_INTERVALS);\nawait kv.enqueue(job, { backoffSchedule });","typeGuard":"function isValidBackoffSchedule(arr: unknown): arr is number[] { return Array.isArray(arr) && arr.length <= 5 && arr.every((i) => typeof i === \"number\" && Number.isFinite(i) && i >= 0 && i <= 60 * 60 * 1000); }","tryCatchPattern":null,"preventionTips":["Cap generated exponential schedules at 5 entries.","Design retry ladders around the 5-interval limit plus a dead-letter path.","Validate imported retry policies before use."],"tags":["kv","queue","retry","backoff","limits"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}