{"record":{"id":"0777fc28c0899adf","repo":"chatboxai/chatbox","slug":"backup-uncompressed-size-exceeds-the-safety-limit","errorCode":null,"errorMessage":"Backup uncompressed size exceeds the safety limit","messagePattern":"Backup uncompressed size exceeds the safety limit","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/packages/backup/export-backup.ts","lineNumber":118,"sourceCode":"    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\n      if (totalUncompressedBytes > DEFAULT_ZIP_LIMITS.maxTotalUncompressedBytes) {\n        throw new Error('Backup uncompressed size exceeds the safety limit')\n      }\n      yield entry\n      continue\n    }\n    let entryBytes = 0\n    const data = entry.data\n    yield {\n      ...entry,\n      data: (async function* () {\n        for await (const chunk of data) {\n          entryBytes += chunk.length\n          totalUncompressedBytes += chunk.length\n          if (entryBytes > maxEntryBytes) throw new Error(`Backup entry is too large: ${entry.path}`)\n          if (totalUncompressedBytes > DEFAULT_ZIP_LIMITS.maxTotalUncompressedBytes) {\n            throw new Error('Backup uncompressed size exceeds the safety limit')\n          }\n          yield chunk\n        }","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/packages/backup/export-backup.ts#L100-L136","documentation":"Thrown by enforceArchiveLimits() in the Uint8Array branch when the running total of uncompressed bytes (accumulated across all entries so far) exceeds DEFAULT_ZIP_LIMITS.maxTotalUncompressedBytes (4 GiB). This is the whole-archive uncompressed-size guard, preventing a backup from producing a zip whose decompressed form is unbounded — a zip-bomb defense. It fires after the per-entry check (116) on the same entry.","triggerScenarios":"The sum of all entry.data.length values (for Uint8Array entries seen so far, plus any streaming entries already counted) crosses 4 GiB. With many sessions and resources, the cumulative size triggers this before any single entry hits its own limit. The check runs per-entry as they stream through.","commonSituations":"A user with a large conversation history and many image/file attachments; accumulated resources over months of use; a backup scope that includes all global resources. The 4 GiB ceiling matches a practical memory/disk budget for the renderer process.","solutions":["Narrow the export scope (fewer conversations, exclude global resources).","Archive older conversations to a separate backup file so each stays under 4 GiB uncompressed.","Prune large/unused resources from storage before exporting.","If the data is legitimately larger, split the export into multiple backup files by date range."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const MAX_TOTAL = 4 * 1024 * 1024 * 1024\nfunction estimateUncompressedSize(sessions: unknown[]): number {\n  // sum known blob sizes; rough pre-export check\n  return sessions.reduce((acc, s) => acc + estimateSessionBytes(s), 0)\n}\nif (estimateUncompressedSize(sessions) > MAX_TOTAL) {\n  throw new Error('Combined uncompressed size exceeds 4 GiB; narrow the scope')\n}","typeGuard":null,"tryCatchPattern":"try {\n  await exportBackup({ items: ['conversations'] })\n} catch (error) {\n  if (error instanceof Error && /uncompressed size exceeds/i.test(error.message)) {\n    showToast('Backup exceeds the 4 GiB safety limit. Export fewer conversations or resources.')\n  } else throw error\n}","preventionTips":["Narrow the export scope to keep cumulative uncompressed bytes under 4 GiB.","Split backups by date range or session set into multiple files.","Prune large or duplicate resources from storage before exporting."],"tags":["backup","export","size-limit","zip","archive"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}