{"record":{"id":"00b634e6d756830d","repo":"chatboxai/chatbox","slug":"backup-entry-checksum-mismatch-descriptor-path","errorCode":null,"errorMessage":"Backup entry checksum mismatch: ${descriptor.path}","messagePattern":"Backup entry checksum mismatch: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/packages/backup/import-backup.ts","lineNumber":96,"sourceCode":"}\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}`)\n    if (staged.checksum.value !== descriptor.checksum.value) {\n      throw new Error(`Backup entry checksum mismatch: ${descriptor.path}`)\n    }\n  }\n  for (const path of stagedEntries.keys()) {\n    if (!expectedPaths.has(path)) throw new Error(`Backup contains an entry not listed in manifest: ${path}`)\n  }\n  if (expectedPaths.size !== stagedEntries.size) throw new Error('Backup manifest entry list is incomplete')\n  validateBackupManifestGraph(manifest)\n}\n\nasync function readStagedResource(storage: BackupStorage, plan: Pick<ResourceWritePlan, 'resource' | 'tempKey'>) {\n  const base64 = await storage.getBlob(plan.tempKey)\n  if (base64 === null) throw new Error(`Staged resource is missing: ${plan.resource.path}`)\n  return decodeStoredBlob(base64ToBytes(base64), plan.resource.encoding, plan.resource.mimeType)\n}\n\nasync function findAvailableCollisionKey(storage: BackupStorage, originalKey: string, reserved: Set<string>) {\n  for (let attempt = 0; attempt < 100; attempt++) {\n    let candidatePrefix = 'resource:imported'","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/renderer/packages/backup/import-backup.ts#L78-L114","documentation":"Thrown when an entry's recomputed sha256 checksum differs from the checksum declared in the manifest. The size check (line 94) happens first; reaching the checksum check (line 95-97) means sizes matched but content differs, signalling corruption or tampering. Propagates after rollback.","triggerScenarios":"The bytes extracted for descriptor.path hash to a different sha256 than descriptor.checksum.value.","commonSituations":"Bit-rot or transfer corruption of the backup file; a manifest swapped from a different archive; deliberate tampering; a file modified inside the zip after export.","solutions":["Re-obtain the backup from a trusted source.","Re-create the backup and re-import.","If you intentionally edited content, regenerate the manifest so checksums match (not recommended for production data)."],"exampleFix":"// before: importing a file whose bytes drifted from the manifest\nawait importBackupArchive(file, options)\n// after: re-verify each descriptor checksum before import\nfor (const d of descriptors) {\n  const bytes = await readEntry(d.path)\n  if ((await sha256Checksum(bytes)).value !== d.checksum.value) {\n    throw new Error('Checksum failed for ' + d.path)\n  }\n}","handlingStrategy":"validation","validationCode":"// Recompute each descriptor's sha256 from the archive bytes and compare before importing.\nfor (const d of descriptors) {\n  const bytes = await readZipEntry(file, d.path)\n  if ((await sha256Checksum(bytes)).value !== d.checksum.value) {\n    throw new Error('Checksum verification failed for ' + d.path)\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await importBackupArchive(file, options)\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith('Backup entry checksum mismatch')) {\n    // File is corrupt or tampered; obtain a fresh copy from a trusted source.\n    throw new Error('Backup failed integrity check', { cause: error })\n  }\n  throw error\n}","preventionTips":["Transport backups over channels that preserve bytes end-to-end (avoid re-encoding transfers).","Store an outer checksum of the whole .backup file and verify it before import.","Do not modify files inside the archive after export."],"tags":["backup","import","checksum","integrity","corruption"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}