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

  1. Split the recording into smaller files (per-session or per-24h archive) and import them individually.
  2. Compress/trim the trace before import — remove redundant buckets or archive history.
  3. Increase the check's intent by pre-trimming the file: strip interaction logs or onsets arrays if your tooling allows, keeping the tape.
  4. 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

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


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)