{"record":{"id":"e2b619d683e344cc","repo":"Hmbown/CodeWhale","slug":"pet-import-exceeds-64-mib","errorCode":null,"errorMessage":"Pet import exceeds 64 MiB.","messagePattern":"Pet import exceeds 64 MiB\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/src/ui/pet.ts","lineNumber":189,"sourceCode":"mode.onchange = async () => {\n  if (!await mayLeave()) { mode.value = worldMode; return; }\n  stopFollowing();\n  if (mode.value === 'replay' && imported) {\n    tape = imported.world.tape; interactions = [...imported.world.interactions]; source.textContent = imported.name;\n    seek.max = String(Math.max(90, imported.world.endTimeMs / 1000));\n    ++generation; silence(); adoptWorld(imported.world);\n    message.textContent = 'Returned to the imported world at its current pose.'; return;\n  }\n  expressionVersion = 2;\n  tape = mode.value === 'demo' ? compilePetTelemetry(petDemoEvents(), 80_000) : [];\n  interactions = []; seek.max = mode.value === 'demo' ? '80' : '120';\n  source.textContent = mode.value === 'demo' ? 'Event demo · synthetic telemetry' : 'Wild · simulated creature'; rebuild();\n  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.';\n};\nget<HTMLInputElement>('file').onchange = async event => {\n  const input = event.target as HTMLInputElement, file = input.files?.[0]; if (!file) return;\n  try {\n    if (file.size > 64 * 1024 * 1024) throw new Error('Pet import exceeds 64 MiB.');\n    const text = await file.text(); let replay: unknown;\n    try { replay = JSON.parse(text); } catch { /* JSONL and trace imports follow below. */ }\n    let next: PetWorld;\n    if (replay && typeof replay === 'object' && 'petReplayVersion' in replay) next = PetWorld.fromRecording(points, replay);\n    else {\n      let nextTape: readonly PetBucket[];\n      const first = replay ?? JSON.parse(text.split(/\\r?\\n/).find(line => line.trim()) || '{}');\n      if (first && typeof first === 'object' && 'version' in first && first.version === 1 && 'simTimeMs' in first) nextTape = decodePetJSONL(text);\n      else {\n        const traces = importTrace(text, file.name, { privacy: 'metadata' });\n        if (traces.length !== 1) throw new Error('Choose one recording to import.');\n        nextTape = compilePetTelemetry(traces[0].events, traces[0].duration);\n      }\n      next = new PetWorld(points, nextTape, [], 2, true);\n    }\n    if (!await mayLeave()) return;\n    adoptImported(next, `Local replay · ${file.name}`);\n    message.textContent = 'Recording loaded locally, including its current pose, interactions and score.';","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/src/ui/pet.ts#L171-L207","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (user side)\n// selecting a 200MB trace.json in the import picker\n// after\n// split it: split -b 60M trace.json trace-part- && import parts individually","handlingStrategy":"validation","validationCode":"if (file.size > 64 * 1024 * 1024) { alert('Please import a file under 64 MiB.'); return; }","typeGuard":"null","tryCatchPattern":"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; }","preventionTips":["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."],"tags":["file-import","size-limit","ui"],"backgroundTag":"payload-too-large","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"}