chatboxai/chatbox · error · Error
Backup entry checksum mismatch: ${descriptor.path}
Error message
Backup entry checksum mismatch: ${descriptor.path} What it means
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.
Source
Thrown at src/renderer/packages/backup/import-backup.ts:96
}
function validateManifestEntries(manifest: BackupManifest, stagedEntries: Map<string, StagedEntry>) {
const descriptors = [
manifest.data.settings,
manifest.data.copilots,
manifest.data.sessionSettings,
...manifest.sessions,
...manifest.resources,
].filter((entry): entry is NonNullable<typeof entry> => Boolean(entry))
const expectedPaths = new Set<string>([BACKUP_MANIFEST_PATH])
for (const descriptor of descriptors) {
if (expectedPaths.has(descriptor.path)) throw new Error(`Manifest contains a duplicate path: ${descriptor.path}`)
expectedPaths.add(descriptor.path)
const staged = stagedEntries.get(descriptor.path)
if (!staged) throw new Error(`Backup entry is missing: ${descriptor.path}`)
if (staged.size !== descriptor.size) throw new Error(`Backup entry size mismatch: ${descriptor.path}`)
if (staged.checksum.value !== descriptor.checksum.value) {
throw new Error(`Backup entry checksum mismatch: ${descriptor.path}`)
}
}
for (const path of stagedEntries.keys()) {
if (!expectedPaths.has(path)) throw new Error(`Backup contains an entry not listed in manifest: ${path}`)
}
if (expectedPaths.size !== stagedEntries.size) throw new Error('Backup manifest entry list is incomplete')
validateBackupManifestGraph(manifest)
}
async function readStagedResource(storage: BackupStorage, plan: Pick<ResourceWritePlan, 'resource' | 'tempKey'>) {
const base64 = await storage.getBlob(plan.tempKey)
if (base64 === null) throw new Error(`Staged resource is missing: ${plan.resource.path}`)
return decodeStoredBlob(base64ToBytes(base64), plan.resource.encoding, plan.resource.mimeType)
}
async function findAvailableCollisionKey(storage: BackupStorage, originalKey: string, reserved: Set<string>) {
for (let attempt = 0; attempt < 100; attempt++) {
let candidatePrefix = 'resource:imported'View on GitHub (pinned to 81571269ad)
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).
Example fix
// before: importing a file whose bytes drifted from the manifest
await importBackupArchive(file, options)
// after: re-verify each descriptor checksum before import
for (const d of descriptors) {
const bytes = await readEntry(d.path)
if ((await sha256Checksum(bytes)).value !== d.checksum.value) {
throw new Error('Checksum failed for ' + d.path)
}
} Defensive patterns
Strategy: validation
Validate before calling
// Recompute each descriptor's sha256 from the archive bytes and compare before importing.
for (const d of descriptors) {
const bytes = await readZipEntry(file, d.path)
if ((await sha256Checksum(bytes)).value !== d.checksum.value) {
throw new Error('Checksum verification failed for ' + d.path)
}
} Try / catch
try {
await importBackupArchive(file, options)
} catch (error) {
if (error instanceof Error && error.message.startsWith('Backup entry checksum mismatch')) {
// File is corrupt or tampered; obtain a fresh copy from a trusted source.
throw new Error('Backup failed integrity check', { cause: error })
}
throw error
} Prevention
- 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.
When it happens
Trigger: The bytes extracted for descriptor.path hash to a different sha256 than descriptor.checksum.value.
Common situations: 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.
Related errors
- Backup entry is missing: ${descriptor.path}
- Backup contains an entry not listed in manifest: ${path}
- Backup JSON entry is too large: ${path}
- Manifest contains a duplicate path: ${descriptor.path}
- Backup manifest entry list is incomplete
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/00b634e6d756830d.
Report an issue: GitHub.