{"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":"exception","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/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/kv/01_db.ts#L79-L115","documentation":"`kv.enqueue(value, { backoffSchedule })` accepts at most 5 retry intervals (`maxQueueBackoffIntervals = 5`); the queue retries a failed message once per entry, and more than five retries have no backend support. A longer array is rejected up front with this TypeError.","triggerScenarios":"Passing six or more entries, e.g. `[1000, 5000, 10000, 30000, 60000, 120000]` — a common exponential ladder copied from another system.","commonSituations":"Porting retry ladders from job libraries (BullMQ, Sidekiq-style 6–8 step backoffs); schedules generated programmatically without a length bound.","solutions":["Trim to the 5 most meaningful intervals (usually keep the early, fast retries and merge the tail)","For more retries, re-enqueue on final failure with a fresh schedule","Assert the length in a helper that builds backoff schedules"],"exampleFix":"// before\nawait kv.enqueue(job, { backoffSchedule: [1000, 5000, 10000, 30000, 60000, 120000] });\n\n// after\nawait kv.enqueue(job, { backoffSchedule: [1000, 5000, 10000, 30000, 60000] });","handlingStrategy":"validation","validationCode":"const MAX_INTERVALS = 5;\nconst backoffSchedule = rawSchedule.slice(0, MAX_INTERVALS);\nawait kv.enqueue(msg, { backoffSchedule });","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build backoff ladders through one helper that caps length at 5","When porting retry configs, map the tail steps into a final re-enqueue instead of a 6th interval","Keep a unit test asserting the schedule length"],"tags":["kv","deno-kv","queue","retry","backoff","validation"],"backgroundTag":"retry-backoff-invalid","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}