{"record":{"id":"822d9ecd33f701ff","repo":"chatboxai/chatbox","slug":"backup-json-entry-is-too-large-path-822d9e","errorCode":null,"errorMessage":"Backup JSON entry is too large: ${path}","messagePattern":"Backup JSON entry is too large: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/packages/backup/import-backup.ts","lineNumber":76,"sourceCode":"    session: Session\n  ) => Promise<{ session: Session; warnings: BackupWarning[]; rollback?: () => Promise<void> }>\n}\n\nexport interface BackupImportResult {\n  manifest: BackupManifest\n  warnings: BackupWarning[]\n  restoredSessionCount: number\n  restoredResourceCount: number\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n  if (signal?.aborted) {\n    throw signal.reason instanceof Error ? signal.reason : new DOMException('Operation canceled', 'AbortError')\n  }\n}\n\nfunction parseJson(bytes: Uint8Array, path: string): unknown {\n  if (bytes.length > MAX_BACKUP_JSON_ENTRY_BYTES) throw new Error(`Backup JSON entry is too large: ${path}`)\n  return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes)) as unknown\n}\n\nfunction validateManifestEntries(manifest: BackupManifest, stagedEntries: Map<string, StagedEntry>) {\n  const descriptors = [\n    manifest.data.settings,\n    manifest.data.copilots,\n    manifest.data.sessionSettings,\n    ...manifest.sessions,\n    ...manifest.resources,\n  ].filter((entry): entry is NonNullable<typeof entry> => Boolean(entry))\n  const expectedPaths = new Set<string>([BACKUP_MANIFEST_PATH])\n  for (const descriptor of descriptors) {\n    if (expectedPaths.has(descriptor.path)) throw new Error(`Manifest contains a duplicate path: ${descriptor.path}`)\n    expectedPaths.add(descriptor.path)\n    const staged = stagedEntries.get(descriptor.path)\n    if (!staged) throw new Error(`Backup entry is missing: ${descriptor.path}`)\n    if (staged.size !== descriptor.size) throw new Error(`Backup entry size mismatch: ${descriptor.path}`)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/packages/backup/import-backup.ts#L58-L94","documentation":"Thrown by parseJson during the import reading phase when an entry's decoded UTF-8 bytes exceed MAX_BACKUP_JSON_ENTRY_BYTES (128 MiB). It guards JSON.parse against pathological inputs. readZipFileEntries already caps each entry via backupEntryByteLimit, so this is a secondary defense; if reached, the import aborts, rollback runs (commitStarted is false, so only temps are cleaned), and the error propagates.","triggerScenarios":"A JSON archive entry (manifest.json, settings.json, copilots.json, session-settings.json, or a sessions/<id>/session.json) is larger than 128 MiB uncompressed and reached parseJson.","commonSituations":"A session with an enormous message history; a hand-edited or future-format archive with a giant JSON entry; entry-limit config bypassed when calling readZipFileEntries.","solutions":["Reduce the offending JSON entry below 128 MiB (split the session, trim message history) and re-export.","Reject the file before import by pre-scanning entry.uncompressedSize.","Raise MAX_BACKUP_JSON_ENTRY_BYTES only after verifying the memory budget for JSON.parse.","Regenerate the backup from a current app version."],"exampleFix":"// before: import blows up parsing a 200 MiB session.json\nawait importBackupArchive(file, options)\n// after: pre-scan and reject oversized entries\nawait readZipFileEntries(file, async (entry) => {\n  if (isBackupJsonPath(entry.path) && entry.uncompressedSize > MAX_BACKUP_JSON_ENTRY_BYTES) {\n    throw new Error('Refusing oversized entry ' + entry.path)\n  }\n})\nawait importBackupArchive(file, options)","handlingStrategy":"try-catch","validationCode":"// Pre-scan the zip's JSON entries and reject any over the JSON cap before importing.\nimport { MAX_BACKUP_JSON_ENTRY_BYTES } from './types'\nimport { isBackupJsonPath } from './archive-layout'\nawait readZipFileEntries(file, async (entry) => {\n  if (isBackupJsonPath(entry.path) && entry.uncompressedSize > MAX_BACKUP_JSON_ENTRY_BYTES) {\n    throw new Error('Entry too large to import: ' + entry.path)\n  }\n})","typeGuard":"// True when a JSON entry's uncompressed size fits the JSON budget.\nconst jsonEntryFits = (uncompressedSize: number): boolean =>\n  uncompressedSize <= MAX_BACKUP_JSON_ENTRY_BYTES","tryCatchPattern":"try {\n  await importBackupArchive(file, options)\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith('Backup JSON entry is too large')) {\n    // The offending path is embedded in the message; trim the source and re-export.\n    throw new Error('Cannot import: a JSON entry exceeds 128 MiB', { cause: error })\n  }\n  throw error\n}","preventionTips":["Trim very long conversation histories before exporting so session.json stays well under the cap.","Inspect uncompressed sizes from the zip central directory before invoking the importer.","Keep MAX_BACKUP_JSON_ENTRY_BYTES aligned with what JSON.parse can safely handle in the target runtime."],"tags":["backup","import","json","size-limit","validation"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}