santifer/career-ops · critical · RangeError

No safe report-number range remains

Error message

No safe report-number range remains

What it means

Inside the reservation retry loop, the code checks that both `base` (the starting ID) and `end` (base + count - 1) are safe integers before attempting to claim slots. If either exceeds Number.MAX_SAFE_INTEGER (~9 quadrillion), it throws a RangeError. This is an overflow guard — in practice it is effectively unreachable because the reports directory would be impossibly large.

Source

Thrown at reserve-report-num.mjs:181

  mkdirSync(reportsDir, { recursive: true });

  const lock = await acquireTrackerLock(trackerLockDirFor(trackerPath), {
    timeoutMs: Number(process.env.CAREER_OPS_TRACKER_LOCK_TIMEOUT_MS) || 60_000,
    retryMs: Number(process.env.CAREER_OPS_TRACKER_LOCK_RETRY_MS) || 75,
    staleMs: Number(process.env.CAREER_OPS_TRACKER_LOCK_STALE_MS) || 10 * 60_000,
    tracker: trackerPath,
    ...options.lockOptions,
  });

  try {
    let occupied = collectOccupied(reportsDir, trackerPath);
    let base = highestNumber(occupied) + 1;
    const token = randomUUID();

    for (let tries = 0; tries < MAX_RETRIES; tries++) {
      const end = base + (count - 1);
      if (!Number.isSafeInteger(base) || !Number.isSafeInteger(end)) {
        throw new RangeError('No safe report-number range remains');
      }
      const claimed = [];
      let failedAt = null;
      for (let num = base; num <= end; num++) {
        if (claimSlot(reportsDir, num, occupied, token)) {
          claimed.push(num);
        } else {
          failedAt = num;
          break;
        }
      }
      if (failedAt == null) {
        Object.defineProperty(claimed, RESERVATION_TOKEN, { value: token });
        return claimed;
      }

      for (const num of claimed) releaseSlot(reportsDir, num, { token });
      occupied = collectOccupied(reportsDir, trackerPath);

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Inspect the reports/ directory for corrupted sentinel files with unexpectedly large numbers in their names and remove them.
  2. If this appears in tests, check that mocks for highestNumber/collectOccupied return realistic values.
  3. As a guard, cap base before the loop: if (base > 1_000_000) throw new Error('report numbering corrupted — inspect reports/ dir').
  4. Audit collectOccupied/highestNumber for any parsing that could inflate numbers.
Defensive patterns

Strategy: validation

Validate before calling

const occupied = collectOccupied(reportsDir, trackerPath);
const base = highestNumber(occupied) + 1;
if (!Number.isSafeInteger(base) || !Number.isSafeInteger(base + count - 1)) {
  throw new Error('Report numbering overflow — inspect reports/ for corrupted sentinels');
}

Prevention

When it happens

Trigger: highestNumber(occupied) returning a value near Number.MAX_SAFE_INTEGER, then base = that + 1 overflowing; or count being large enough that base + count - 1 overflows. This requires billions of report files to exist.

Common situations: This error is not realistically hit in normal operation. It could theoretically surface if `occupied` collection logic were corrupted to return artificially huge numbers (e.g., parsing a sentinel filename with a huge embedded number), or in a long-running test that mocks highestNumber().

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/16b1cc55eab9b587. Report an issue: GitHub.