{"record":{"id":"1c2b1a5077896cd0","repo":"Hmbown/CodeWhale","slug":"pet-archive-numbering-is-exhausted-existing-files-were","errorCode":null,"errorMessage":"Pet archive numbering is exhausted; existing files were preserved.","messagePattern":"Pet archive numbering is exhausted; existing files were preserved\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/scripts/lib/pet-recorder.mjs","lineNumber":91,"sourceCode":"        length += bytesRead;\n      }\n      if (length !== Number(held.size)) throw new Error('The previous pet recording changed while reading; it was preserved.');\n      const text = new TextDecoder('utf-8', { fatal: true }).decode(contents.subarray(0, length));\n      if (text && !text.endsWith('\\n')) throw new Error('The previous pet recording has an incomplete final row; it was preserved.');\n      decodePetJSONL(text);\n      const unchanged = await output.stat({ bigint: true });\n      if (unchanged.size !== original.size || unchanged.mtimeNs !== original.mtimeNs)\n        throw new Error('The previous pet recording changed while reading; it was preserved.');\n      bytes = length; restart = true; expectedMtime = original.mtimeNs;\n      // Continue archive numbering without collecting a growing directory list.\n      const prefix = `${basename(path)}.segment-`;\n      for await (const entry of await opendir(dirname(path))) {\n        if (!entry.name.startsWith(prefix)) continue;\n        const suffix = entry.name.slice(prefix.length);\n        if (!/^[0-9]{6,}\\.jsonl$/.test(suffix)) continue;\n        const number = Number(suffix.slice(0, -6));\n        if (!Number.isSafeInteger(number) || number >= Number.MAX_SAFE_INTEGER)\n          throw new Error('Pet archive numbering is exhausted; existing files were preserved.');\n        segment = Math.max(segment, number);\n      }\n    }\n    expectedMtime ??= (await output.stat({ bigint: true })).mtimeNs;\n  } catch (error) { try { await output?.close(); } finally { lock.close(); } throw error; }\n  return {\n    async append(bucket) {\n      if (!output || busy) throw new Error('Pet recorder is closed or already writing.');\n      validatePetBucket(bucket);\n      busy = true;\n      try {\n        await lock.check();\n        const held = await output.stat({ bigint: true }), current = await lstat(path, { bigint: true });\n        if (!current.isFile() || held.dev !== current.dev || held.ino !== current.ino || held.size !== BigInt(bytes) || held.mtimeNs !== expectedMtime)\n          throw new Error('The live pet recording was changed or replaced externally; existing files were preserved.');\n        const encode = seq => encodePetJSONL([{ ...bucket, sequence: seq, simTimeMs: seq * PET_BIN_MS }]);\n        let row = encode(sequence), size = Buffer.byteLength(row);\n        if (restart || sequence >= maxBuckets || bytes + size > maxBytes) {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/scripts/lib/pet-recorder.mjs#L73-L109","documentation":"Thrown while scanning the recording directory for existing `.segment-NNNNNN.jsonl` archives when a suffix encodes a segment number at or above Number.MAX_SAFE_INTEGER. The recorder refuses to keep incrementing numbering because it could no longer represent the next segment number safely, and aborts without touching existing files.","triggerScenarios":"A directory containing a file named `<basename>.segment-9007199254740991.jsonl` or larger (7+ digits beyond the safe range) when the recorder initializes; also a manually created or corrupted segment file with an absurd number.","commonSituations":"Hand-crafted or test files that match the segment pattern with a huge numeric suffix; corrupted directory contents from a previous misbehaving tool.","solutions":["Find the offending file: `ls | grep -E 'segment-[0-9]{6,}\\.jsonl$'` and inspect its numeric suffix.","Rename or remove the file with the out-of-range number (it is not a real archive this recorder created).","If it is genuine history, renumber segments into the safe range and update any references.","Retry creating the recorder after cleanup."],"exampleFix":"// before: bogus file in recording dir\npet-recording.segment-99999999999999999999.jsonl\n// after: remove or renumber\nmv pet-recording.segment-99999999999999999999.jsonl /tmp/quarantine/","handlingStrategy":"validation","validationCode":"import { readdir } from 'node:fs/promises';\nconst dir = dirname(recordingPath);\nconst bad = (await readdir(dir)).filter(n => /^\\.segment-|segment-[0-9]{7,}\\.jsonl$/.test(n));\nif (bad.some(n => Number(n.match(/segment-([0-9]+)\\./)[1]) >= Number.MAX_SAFE_INTEGER)) {\n  throw new Error(`clean up out-of-range segment files: ${bad.join(', ')}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not hand-create files matching `<name>.segment-*.jsonl` in the recording directory","Quarantine stray/huge-numbered segment files before starting the recorder","Keep segment numbering below Number.MAX_SAFE_INTEGER (real usage never approaches it)"],"tags":["filesystem","naming","numeric-limits"],"backgroundTag":"value-out-of-range","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}