Hmbown/CodeWhale · error · Error
Pet import exceeds 64 MiB.
Error message
Pet import exceeds 64 MiB.
What it means
The pet UI's file import handler rejects any file larger than 64 MiB before parsing, throwing this error to prevent decoding an oversized telemetry recording into memory (JSON.parse on a huge file would freeze or crash the tab).
Solutions
- Split the recording into smaller files (per-session or per-24h archive) and import them individually.
- Compress/trim the trace before import — remove redundant buckets or archive history.
- Increase the check's intent by pre-trimming the file: strip interaction logs or onsets arrays if your tooling allows, keeping the tape.
- If large imports are legitimate for your use case, chunk the import rather than bypassing the size guard.
Example fix
// before (user side) // selecting a 200MB trace.json in the import picker // after // split it: split -b 60M trace.json trace-part- && import parts individually
Defensive patterns
Strategy: validation
Validate before calling
if (file.size > 64 * 1024 * 1024) { alert('Please import a file under 64 MiB.'); return; } Type guard
null
Try / catch
try { await importPetFile(file); } catch (e) { if (/Pet import exceeds 64 MiB/.test(e.message)) showMessage('Split or compress the recording below 64 MiB.'); else throw e; } Prevention
- Check file.size in the change handler before reading the file.
- Split long recordings per session/24h at export time.
- Reset the input element value after a rejected pick so re-selecting the same file re-fires the handler.
When it happens
Trigger: Selecting (via the file input) a telemetry/recording file whose size exceeds 64 * 1024 * 1024 bytes — e.g. a multi-day event-v1 trace or an export that accidentally embedded duplicated tapes.
Common situations: Importing a large OTLP/JSONL trace dump instead of a bounded recording; an export job that accumulated unarchived 24h tapes into one giant file; users selecting the wrong file (a video or dataset) in the picker.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- AutomationEditorConflict
- AutomationEditorInvalidWorkspace
- bounded provider catalog cache exceeds its write limit
- bundle at is bytes; the limit is bytes
- download exceeds compressed size cap of bytes
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/e2b619d683e344cc.
Report an issue: GitHub.
Appendix: source
Thrown at pet/src/ui/pet.ts:189
mode.onchange = async () => {
if (!await mayLeave()) { mode.value = worldMode; return; }
stopFollowing();
if (mode.value === 'replay' && imported) {
tape = imported.world.tape; interactions = [...imported.world.interactions]; source.textContent = imported.name;
seek.max = String(Math.max(90, imported.world.endTimeMs / 1000));
++generation; silence(); adoptWorld(imported.world);
message.textContent = 'Returned to the imported world at its current pose.'; return;
}
expressionVersion = 2;
tape = mode.value === 'demo' ? compilePetTelemetry(petDemoEvents(), 80_000) : [];
interactions = []; seek.max = mode.value === 'demo' ? '80' : '120';
source.textContent = mode.value === 'demo' ? 'Event demo · synthetic telemetry' : 'Wild · simulated creature'; rebuild();
message.textContent = mode.value === 'demo' ? 'Synthetic event-v1 telemetry uses the same derivation as imported traces.' : 'Wild mode is a simulated creature. Import event-v1, OTLP, or Codewhale telemetry to see work.';
};
get<HTMLInputElement>('file').onchange = async event => {
const input = event.target as HTMLInputElement, file = input.files?.[0]; if (!file) return;
try {
if (file.size > 64 * 1024 * 1024) throw new Error('Pet import exceeds 64 MiB.');
const text = await file.text(); let replay: unknown;
try { replay = JSON.parse(text); } catch { /* JSONL and trace imports follow below. */ }
let next: PetWorld;
if (replay && typeof replay === 'object' && 'petReplayVersion' in replay) next = PetWorld.fromRecording(points, replay);
else {
let nextTape: readonly PetBucket[];
const first = replay ?? JSON.parse(text.split(/\r?\n/).find(line => line.trim()) || '{}');
if (first && typeof first === 'object' && 'version' in first && first.version === 1 && 'simTimeMs' in first) nextTape = decodePetJSONL(text);
else {
const traces = importTrace(text, file.name, { privacy: 'metadata' });
if (traces.length !== 1) throw new Error('Choose one recording to import.');
nextTape = compilePetTelemetry(traces[0].events, traces[0].duration);
}
next = new PetWorld(points, nextTape, [], 2, true);
}
if (!await mayLeave()) return;
adoptImported(next, `Local replay · ${file.name}`);
message.textContent = 'Recording loaded locally, including its current pose, interactions and score.';View on GitHub (pinned to 433685b202)