Hmbown/CodeWhale · error · Error
Pet tape exceeds 64 MiB.
Error message
Pet tape exceeds 64 MiB.
What it means
decodePetJSONL enforces a hard size limit of 64 MiB on the raw pet tape text before parsing, to bound memory and parse cost when replaying a day's activity. A larger tape is rejected outright with 'Pet tape exceeds 64 MiB.'
Solutions
- Check the tape file size (ls -lh) and split or truncate it into chunks under 64 MiB before decoding.
- Decode the tape day-by-day or in segments, decoding each chunk separately instead of one string.
- Rotate the tape at write time (start a new file per 24h/session) so it never exceeds the cap.
- If the tape is bloated by duplicate rows, deduplicate by sequence before decoding; note the separate 216,000-row (24h) cap also applies.
Example fix
// before
const tape = fs.readFileSync(dayFiles[0] + ',' + dayFiles[1]);
pets.decodePetJSONL(tape.toString()); // 80 MiB combined
// after
for (const f of [dayFile1, dayFile2]) {
const text = fs.readFileSync(f);
pets.decodePetJSONL(text); // each under 64 MiB
} Defensive patterns
Strategy: try-catch
Validate before calling
const stats = fs.statSync(tapePath);
if (stats.size > 64 * 1024 * 1024) throw new Error('split or rotate tape ' + tapePath + ' before decoding'); Type guard
null
Try / catch
try {
pets.decodePetJSONL(text);
} catch (e) {
if (e.message === 'Pet tape exceeds 64 MiB.') decodeInChunks(splitTape(text));
else throw e;
} Prevention
- Rotate tape files per day/session so no single file can pass 64 MiB.
- Check file size before reading a tape into memory.
- Decode in chunks rather than concatenating multiple tapes.
When it happens
Trigger: Calling decodePetJSONL(text) where text.length > 67108864 — e.g. loading a tape file that was never rotated/truncated, concatenating multiple day-tapes, or a runaway producer appending unbounded rows.
Common situations: Long-running sessions whose JSONL tape grew past the cap; a bug duplicating bucket rows; passing the wrong (combined) file to the decoder.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- bounded provider catalog cache exceeds its write limit
- MCP exceeded the -byte aggregate catalog limit
- Pet tape exceeds 64 MiB.
- Pet tape exceeds 64 MiB.
- provider catalog scope
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/0e2e5fd82ebaa8e6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/pet_watch/pet-native.js:1115
const pet_sim_js_1 = require("./pet-sim.js");
/** One projection for imports, demos and recorded live snapshots. Times are ms.
* These are aesthetic encodings of measured events, never model confidence. */
exports.PET_BIN_MS = 400;
function validatePetBucket(value) {
(0, pet_sim_js_1.validatePetState)(value);
const b = value;
if (!b || typeof b !== 'object' || b.version !== 1 || !Number.isSafeInteger(b.sequence) || b.sequence < 0 || b.sequence > pet_sim_js_1.PET_MAX_SECONDS * 2.5
|| b.simTimeMs !== b.sequence * exports.PET_BIN_MS || b.durationMs !== exports.PET_BIN_MS
|| !model_js_1.CATEGORIES.includes(b.channel) || typeof b.waiting !== 'boolean'
|| !Array.isArray(b.agentIds) || b.agentIds.length > 250_000 || b.agentIds.some(id => typeof id !== 'string' || !id || id.length > 4096)
|| !Number.isSafeInteger(b.errors) || b.errors < 0 || b.errors > 250_000
|| !Array.isArray(b.onsets) || b.onsets.length !== 13 || b.onsets.some(n => !Number.isSafeInteger(n) || n < 0 || n > 250_000)
|| !Array.isArray(b.activeMs) || b.activeMs.length !== 13 || b.activeMs.some(n => !Number.isFinite(n) || n < 0 || n > 100_000_000))
throw new Error('Invalid version 1 pet bucket.');
}
function decodePetJSONL(text) {
if (text.length > 64 * 1024 * 1024)
throw new Error('Pet tape exceeds 64 MiB.');
const rows = text.split(/\r?\n/).filter(line => line.trim()).map(line => JSON.parse(line));
if (rows.length > 216_000)
throw new Error('Pet tape exceeds 24 hours.');
return rows.map((row, i) => { validatePetBucket(row); if (row.sequence !== i)
throw new Error('Non-contiguous pet tape.'); return row; });
}
/** A live file must advance before its contents count as a new observation.
* Existing bytes, duplicate samples and a restarted sequence establish a
* baseline; they never replay an old onset or human request. Drivers supply a
* bounded tail and reset this cursor after suspension or a new attachment. */
class PetLiveTape {
sequence;
reset() { this.sequence = undefined; }
readTail(text) {
if (!text) {
this.reset();
return;
}View on GitHub (pinned to 73e0f67d83)