{"record":{"id":"e4df04bd749ff67d","repo":"Hmbown/CodeWhale","slug":"recording-exceeds-the-64-mib-export-limit-the-current-world","errorCode":null,"errorMessage":"Recording exceeds the 64 MiB export limit. The current world was kept.","messagePattern":"Recording exceeds the 64 MiB export limit\\. The current world was kept\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/src/ui/pet.ts","lineNumber":217,"sourceCode":"        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.';\n  } catch (error) { message.textContent = error instanceof Error ? error.message : 'Unable to import this file.'; }\n  finally { input.value = ''; }\n};\nget('save').onclick = () => {\n  try {\n    const chunks: string[] = []; let bytes = 0;\n    for (let index = 0; ; index++) {\n      const chunk = world.recordingChunk(index); if (chunk === null) break;\n      bytes += new TextEncoder().encode(chunk).length;\n      if (bytes > 64 * 1024 * 1024) throw new Error('Recording exceeds the 64 MiB export limit. The current world was kept.');\n      chunks.push(chunk);\n    }\n    const blob = new Blob(chunks, { type: 'application/json' });\n    const url = URL.createObjectURL(blob), a = document.createElement('a'); a.href = url; a.download = 'codewhale-pet-replay.json'; a.click(); setTimeout(() => URL.revokeObjectURL(url), 1000);\n  } catch (error) { message.textContent = error instanceof Error ? error.message : 'Unable to export the recording. The current world was kept.'; }\n};\nget('follow').onclick = async () => {\n  // A browser-granted read handle is the same local JSONL seam native hosts use.\n  // It is never persisted: reloading restores the accepted recording, not access.\n  const picker = (window as Window & { showOpenFilePicker?: () => Promise<{ getFile(): Promise<File> }[]> }).showOpenFilePicker;\n  if (!picker) { message.textContent = 'This browser cannot follow local files. Import a tape to replay it, or use the native pet for live telemetry.'; return; }\n  try {\n    const [handle] = await picker.call(window); if (!handle) return;\n    const file = await handle.getFile();\n    if (!await mayLeave()) return;\n    stopFollowing(); const ticket = liveGeneration;\n    mode.value = 'live'; paused = false; get('pause').textContent = 'Pause'; get('pause').setAttribute('aria-pressed', 'false');\n    get<HTMLButtonElement>('pause').disabled = true; seek.disabled = true;","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/src/ui/pet.ts#L199-L235","documentation":"Thrown by the save/export handler while incrementally serializing `world.recordingChunk(index)` chunks and accumulating their UTF-8 byte size. If the accumulated recording exceeds 64 MiB the export is aborted; the live world is untouched because the catch handler only updates the message text.","triggerScenarios":"Clicking the `save` button after a recording has grown past 64 MiB of serialized JSON chunk data (long-running sessions with dense telemetry).","commonSituations":"Leaving the pet running for hours with a large tape; high-frequency interaction recording; exporting after importing a near-limit replay and letting it grow.","solutions":["Shorten the session or reset the recording before exporting.","Trim or sample the recorded tape to reduce size under the limit.","Split the recording and export in parts if long captures are required."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"let bytes = 0;\nfor (let i = 0; ; i++) { const c = world.recordingChunk(i); if (c === null) break; bytes += new TextEncoder().encode(c).length; }\nif (bytes > 64 * 1024 * 1024) trimRecording();","typeGuard":"null","tryCatchPattern":"try { exportRecording(); } catch (e) { message.textContent = e.message; /* world remains usable */ }","preventionTips":["Periodically reset or trim long recordings.","Estimate export size before clicking save on marathon sessions.","Warn users when the recording approaches the 64 MiB limit."],"tags":["export","size-limit"],"backgroundTag":"file-size-limit-exceeded","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"}