{"record":{"id":"26a4ed6fd9adbb92","repo":"santifer/career-ops","slug":"reservation-count-must-be-an-integer-from-1-to-m","errorCode":null,"errorMessage":"Reservation count must be an integer from 1 to ${MAX_COUNT}","messagePattern":"Reservation count must be an integer from 1 to (.+?)","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"reserve-report-num.mjs","lineNumber":158,"sourceCode":"  if (!Number.isSafeInteger(pid) || pid <= 0) return false;\n  try {\n    process.kill(pid, 0);\n    return true;\n  } catch (err) {\n    return err?.code === 'EPERM';\n  }\n}\n\n/**\n * Reserve one or more contiguous report IDs.\n *\n * @param {number} [count=1] Number of IDs to reserve (1-50).\n * @param {object} [options] Path and lock overrides.\n * @returns {Promise<number[]>} Reserved numeric IDs.\n */\nexport async function reserveReportNumbers(count = 1, options = {}) {\n  if (!Number.isInteger(count) || count < 1 || count > MAX_COUNT) {\n    throw new RangeError(`Reservation count must be an integer from 1 to ${MAX_COUNT}`);\n  }\n\n  const reportsDir = reportsDirFor(options);\n  const trackerPath = trackerPathFor(options);\n  mkdirSync(reportsDir, { recursive: true });\n\n  const lock = await acquireTrackerLock(trackerLockDirFor(trackerPath), {\n    timeoutMs: Number(process.env.CAREER_OPS_TRACKER_LOCK_TIMEOUT_MS) || 60_000,\n    retryMs: Number(process.env.CAREER_OPS_TRACKER_LOCK_RETRY_MS) || 75,\n    staleMs: Number(process.env.CAREER_OPS_TRACKER_LOCK_STALE_MS) || 10 * 60_000,\n    tracker: trackerPath,\n    ...options.lockOptions,\n  });\n\n  try {\n    let occupied = collectOccupied(reportsDir, trackerPath);\n    let base = highestNumber(occupied) + 1;\n    const token = randomUUID();","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/reserve-report-num.mjs#L140-L176","documentation":"reserveReportNumbers(count, options) reserves `count` contiguous report IDs under a tracker lock. It throws a RangeError when count is not an integer in [1, MAX_COUNT] where MAX_COUNT = 50. The upper bound prevents runaway reservations and oversized lock hold times.","triggerScenarios":"Calling reserveReportNumbers(0), reserveReportNumbers(-5), reserveReportNumbers(51), reserveReportNumbers(1.5), or reserveReportNumbers(NaN). Passing an unparsed string from a --count CLI flag.","commonSituations":"A batch worker computing count = numberOfWorkers and exceeding 50; a CLI flag parsed as a string ('10') rather than a number; defaulting count to 0 when no workers are needed instead of skipping the call.","solutions":["Validate and clamp count before calling: const c = Math.min(Math.max(1, Math.trunc(Number(count))), 50).","If you genuinely need more than 50 IDs, call reserveReportNumbers in multiple batches of <= 50 and concatenate results.","Parse CLI --count with Number() and guard: if (!Number.isInteger(c) || c < 1 || c > 50) exit with usage.","If count could be 0 (no work), skip the reserveReportNumbers call entirely rather than passing 0."],"exampleFix":"// before\nconst ids = await reserveReportNumbers(workerCount); // throws if workerCount > 50\n\n// after\nconst capped = Math.min(Math.max(1, Math.trunc(Number(workerCount))), 50);\nconst ids = await reserveReportNumbers(capped);","handlingStrategy":"validation","validationCode":"function validateReservationCount(count) {\n  const c = Number(count);\n  if (!Number.isInteger(c) || c < 1 || c > 50) {\n    throw new RangeError(`Reservation count must be an integer from 1 to 50`);\n  }\n  return c;\n}\nreserveReportNumbers(validateReservationCount(cliCount));","typeGuard":"function isValidReservationCount(value) {\n  return Number.isInteger(value) && value >= 1 && value <= 50;\n}","tryCatchPattern":"try {\n  const ids = await reserveReportNumbers(count);\n} catch (err) {\n  if (err instanceof RangeError && err.message.includes('Reservation count')) {\n    console.error(`--count must be 1-50, got ${count}`);\n    process.exit(2);\n  }\n  throw err;\n}","preventionTips":["Clamp the count at the CLI boundary: Math.min(Math.max(1, Number(count)), 50).","If you need >50 IDs, batch the reservations and concatenate.","Skip the reservation call when count would be 0 rather than passing 0."],"tags":["validation","report-number","rangeerror","batch-reservation"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}