{"record":{"id":"35c0a283aefe200e","repo":"chatboxai/chatbox","slug":"backup-json-entry-is-too-large-path","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/export-backup.ts","lineNumber":98,"sourceCode":"    name: session.name,\n    starred: session.starred,\n    hidden: session.hidden,\n    archivedAt: session.archivedAt,\n    assistantAvatarKey: session.assistantAvatarKey,\n    picUrl: session.picUrl,\n    backgroundImage: session.backgroundImage,\n    type: session.type,\n    sortOrder: existing?.sortOrder ?? Date.now(),\n    createdAt: existing?.createdAt ?? Date.now(),\n  }\n}\n\nasync function jsonEntry(\n  path: string,\n  value: unknown\n): Promise<{ archive: ZipArchiveEntry; descriptor: BackupJsonEntry }> {\n  const bytes = new TextEncoder().encode(JSON.stringify(value))\n  if (bytes.length > MAX_BACKUP_JSON_ENTRY_BYTES) throw new Error(`Backup JSON entry is too large: ${path}`)\n  return {\n    archive: { path, data: bytes, compress: true },\n    descriptor: { path, size: bytes.length, checksum: await sha256Checksum(bytes) },\n  }\n}\n\nasync function* enforceArchiveLimits(\n  entries: AsyncIterable<ZipArchiveEntry>\n): AsyncGenerator<ZipArchiveEntry, void, unknown> {\n  let entryCount = 0\n  let totalUncompressedBytes = 0\n  for await (const entry of entries) {\n    entryCount++\n    if (entryCount > DEFAULT_ZIP_LIMITS.maxEntries) throw new Error('Backup contains too many entries')\n    const maxEntryBytes = backupEntryByteLimit(entry.path)\n    if (entry.data instanceof Uint8Array) {\n      if (entry.data.length > maxEntryBytes) throw new Error(`Backup entry is too large: ${entry.path}`)\n      totalUncompressedBytes += entry.data.length","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/packages/backup/export-backup.ts#L80-L116","documentation":"Thrown by jsonEntry() during backup export when a single JSON value (serialized via JSON.stringify + TextEncoder.encode) exceeds MAX_BACKUP_JSON_ENTRY_BYTES (128 MiB). This is the per-entry guard for structured JSON archive members (settings, session metadata, message lists) before they enter the zip stream. It prevents a single pathological blob from exhausting memory during compression.","triggerScenarios":"A backup export serializes a session or settings object whose JSON encoding exceeds 128 MiB. This requires an extremely large single session (millions of messages) or a settings blob with a huge embedded data structure. The check runs synchronously after encoding, before sha256 and zip entry creation.","commonSituations":"A single conversation with a very large number of accumulated messages (e.g. an agent loop with thousands of turns and long outputs); a settings object with a massive embedded blob; corrupted/duplicated data inflating one entry. The 128 MiB JSON limit is per-entry; resources (images) use a higher 512 MiB limit via backupEntryByteLimit.","solutions":["Identify which entry (path) exceeds the limit and split the session into smaller conversations before exporting.","Prune very large messages or attachments from the session before backup.","If the entry is legitimately large (e.g. a giant settings blob), raise MAX_BACKUP_JSON_ENTRY_BYTES with awareness of memory impact.","Export a subset of sessions (not 'all conversations') to isolate the oversized one."],"exampleFix":"// before\nconst bytes = new TextEncoder().encode(JSON.stringify(value))\nif (bytes.length > MAX_BACKUP_JSON_ENTRY_BYTES) throw new Error(`Backup JSON entry is too large: ${path}`)\n\n// after — report the size so the user can act\nconst bytes = new TextEncoder().encode(JSON.stringify(value))\nif (bytes.length > MAX_BACKUP_JSON_ENTRY_BYTES) {\n  const mb = Math.round(bytes.length / (1024 * 1024))\n  throw new Error(`Backup JSON entry is too large: ${path} (${mb} MiB > ${MAX_BACKUP_JSON_ENTRY_BYTES / (1024 * 1024)} MiB limit). Split or prune this entry.`)\n}","handlingStrategy":"validation","validationCode":"const MAX_BACKUP_JSON_ENTRY_BYTES = 128 * 1024 * 1024\nfunction estimateJsonBytes(value: unknown): number {\n  // rough estimate without full serialize\n  return new TextEncoder().encode(JSON.stringify(value)).length\n}\nif (estimateJsonBytes(session) > MAX_BACKUP_JSON_ENTRY_BYTES) {\n  throw new Error('Session too large to back up; split it first')\n}","typeGuard":null,"tryCatchPattern":"try {\n  await exportBackup({ items: ['conversations'] })\n} catch (error) {\n  if (error instanceof Error && /Backup JSON entry is too large/i.test(error.message)) {\n    showToast('One conversation is too large. Split or prune it, then try again.')\n  } else throw error\n}","preventionTips":["Split very large sessions into smaller conversations before exporting.","Prune oversized messages or embedded data from sessions.","Export subsets of conversations to isolate which entry exceeds the limit."],"tags":["backup","export","size-limit","json","zip"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}