{"record":{"id":"f021f3152dc51795","repo":"chatboxai/chatbox","slug":"managed-resource-exceeds-the-backup-size-limit","errorCode":null,"errorMessage":"Managed resource exceeds the backup size limit","messagePattern":"Managed resource exceeds the backup size limit","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/renderer/packages/backup/export-backup.ts","lineNumber":305,"sourceCode":"    }\n\n    const resourceCandidateEntries = Array.from(resourceCandidates.entries())\n    for (let index = 0; index < resourceCandidateEntries.length; index++) {\n      throwIfAborted(options.signal)\n      const [storageKey, candidate] = resourceCandidateEntries[index]\n      options.onProgress?.({\n        phase: 'resources',\n        current: index,\n        total: resourceCandidateEntries.length,\n        label: candidate.references.find((reference) => reference.filename)?.filename,\n      })\n      try {\n        const storedValue = await options.storage.getBlob(storageKey)\n        if (storedValue === null) throw new Error('Managed resource is missing from blob storage')\n        const firstReference = candidate.references[0]\n        const encoded = encodeStoredBlob(storedValue, firstReference)\n        if (encoded.bytes.length > MAX_BACKUP_RESOURCE_ENTRY_BYTES) {\n          throw new Error('Managed resource exceeds the backup size limit')\n        }\n        const checksum = await sha256Checksum(encoded.bytes)\n        successfullyReadResourceKeys++\n        const dedupeKey = `${checksum.value}:${encoded.encoding}:${encoded.mimeType}`\n        const existingResource = deduplicatedResources.get(dedupeKey)\n        const sessionIds = unique(\n          candidate.references.flatMap((reference) => (reference.sessionId ? [reference.sessionId] : []))\n        )\n        if (existingResource) {\n          existingResource.originalStorageKeys.push(storageKey)\n          existingResource.sessionIds = unique([...existingResource.sessionIds, ...sessionIds])\n          const candidateScope = resolveResourceScope(candidate)\n          if (\n            existingResource.scope !== candidateScope ||\n            (existingResource.scope === 'session' && existingResource.sessionIds.length !== 1)\n          ) {\n            existingResource.scope = 'shared'\n          }","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/packages/backup/export-backup.ts#L287-L323","documentation":"Thrown when an encoded resource blob's byte length exceeds MAX_BACKUP_RESOURCE_ENTRY_BYTES (512 MiB, defined in types.ts). encodeStoredBlob produces the bytes that would be written into the archive; exceeding the cap would make the archive unwieldy and risk memory exhaustion, so the entry is rejected. Caught in the resource loop (lines 352-359) and recorded as a 'resource-read-failed' warning, so export continues without that resource.","triggerScenarios":"A single managed resource - image, parsed/raw attachment, parsed link, tool result, avatar, background, or copilot image - once encoded (utf8 or data-url-base64) is larger than 512 MiB.","commonSituations":"A user attached a very large video or raw file; a parsed attachment expanded an enormous document; base64 encoding of a binary blob pushed an already-large file over the cap.","solutions":["Reduce the size of the offending resource before exporting (compress, resize, or transcode it).","Remove the large attachment from its session.","Raise MAX_BACKUP_RESOURCE_ENTRY_BYTES in types.ts only after confirming the writer and memory budget can handle larger entries.","Exclude the conversations containing the oversized resource from exportItems."],"exampleFix":"// before: oversized blob silently dropped during export\nconst blob = await storage.getBlob(key)\n// after: downsize or reject before it ever reaches export\nif (blob && base64ToBytes(blob).length > MAX_BACKUP_RESOURCE_ENTRY_BYTES) {\n  await shrinkOrRemoveAttachment(key)\n}\nawait exportBackupArchive(options)","handlingStrategy":"validation","validationCode":"// Before export, flag any managed blob that will exceed the resource cap once encoded.\nimport { MAX_BACKUP_RESOURCE_ENTRY_BYTES } from './types'\nimport { base64ToBytes } from './codec'\nconst oversized: string[] = []\nfor (const key of managedResourceKeys) {\n  const blob = await storage.getBlob(key)\n  if (blob && base64ToBytes(blob).length > MAX_BACKUP_RESOURCE_ENTRY_BYTES) oversized.push(key)\n}","typeGuard":"// True when the blob's decoded size fits the resource entry budget.\nconst withinResourceBudget = (decodedBytes: number): boolean =>\n  decodedBytes <= MAX_BACKUP_RESOURCE_ENTRY_BYTES","tryCatchPattern":null,"preventionTips":["Cap attachment size at ingest time rather than at export time.","Transcode large media before storing so exports never approach the 512 MiB cap.","If you raise MAX_BACKUP_RESOURCE_ENTRY_BYTES, also verify the writer's memory budget and zip limits."],"tags":["backup","export","resource","size-limit","memory"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}