chatboxai/chatbox · error

Unsupported backup entry: ${entry.path}

Error message

Unsupported backup entry: ${entry.path}

What it means

Thrown during the reading phase when an archive entry's path matches none of the recognized patterns: manifest/settings/copilots/session-settings JSON, a session.json, or a resource path. The importer refuses unknown content to avoid silently dropping or mis-staging files. Propagates after rollback.

Source

Thrown at src/renderer/packages/backup/import-backup.ts:250

        })
        const checksum = await sha256Checksum(entry.data)
        const staged: StagedEntry = { path: entry.path, size: entry.uncompressedSize, checksum }
        if (isBackupJsonPath(entry.path) && !isBackupSessionPath(entry.path)) {
          staged.value = parseJson(entry.data, entry.path)
        } else if (isBackupSessionPath(entry.path)) {
          const value = parseJson(entry.data, entry.path)
          if (!isBackupSession(value)) throw new Error(`Invalid session entry: ${entry.path}`)
          const tempKey = `${tempPrefix}:session:${stagedSessionCount++}`
          await options.storage.setItemNow(tempKey, value)
          tempStoreKeys.push(tempKey)
          staged.tempKey = tempKey
        } else if (isBackupResourcePath(entry.path)) {
          const tempKey = `${tempPrefix}:resource:${stagedResourceCount++}`
          await options.storage.setBlob(tempKey, bytesToBase64(entry.data))
          tempBlobKeys.push(tempKey)
          staged.tempKey = tempKey
        } else {
          throw new Error(`Unsupported backup entry: ${entry.path}`)
        }
        stagedEntries.set(entry.path, staged)
      },
      {
        signal: options.signal,
        entryLimits: (path) => ({ maxEntryUncompressedBytes: backupEntryByteLimit(path) }),
      }
    )

    options.onProgress?.({ phase: 'validating', current: 0, total: 1 })
    const manifestValue = stagedEntries.get(BACKUP_MANIFEST_PATH)?.value
    const manifest = BackupManifestSchema.parse(manifestValue)
    validateManifestEntries(manifest, stagedEntries)
    const { plans: resourcePlans, resourceKeyMap } = await createResourcePlans(manifest, stagedEntries, options.storage)
    options.onProgress?.({ phase: 'validating', current: 1, total: 1 })

    const existingStoreKeys = new Set(await options.storage.getAllKeys())
    const changedKeys = [

View on GitHub (pinned to 81571269ad)

Solutions

  1. Use a backup produced by a compatible app version.
  2. Re-zip the archive excluding foreign files (e.g. __MACOSX, .DS_Store).
  3. If extending the format, update isBackupJsonPath/isBackupResourcePath and the staging switch to recognize the new path.
  4. Strip unknown entries from the zip before importing.

Example fix

// before: stray zip entries abort import
await importBackupArchive(file, options)
// after: filter the archive to only known paths before importing
const allowed = (p) =>
  isBackupJsonPath(p) || isBackupResourcePath(p)
await rebuildZipWithout(file, (p) => !allowed(p))
await importBackupArchive(cleanedFile, options)
Defensive patterns

Strategy: validation

Validate before calling

// Reject archives whose entries fall outside recognized path patterns before importing.
import { isBackupJsonPath, isBackupResourcePath } from './archive-layout'
const recognized = (p: string) => isBackupJsonPath(p) || isBackupResourcePath(p)
const unknown = zipEntryPaths.filter((p) => !recognized(p))
if (unknown.length) throw new Error('Unrecognized entries: ' + unknown.join(', '))

Type guard

// True when an entry path is classified as JSON or resource by the layout helpers.
const entryPathIsRecognized = (path: string): boolean =>
  isBackupJsonPath(path) || isBackupResourcePath(path)

Try / catch

try {
  await importBackupArchive(file, options)
} catch (error) {
  if (error instanceof Error && error.message.startsWith('Unsupported backup entry')) {
    // Re-zip without foreign files or use a compatible backup.
    throw new Error('Archive contains unsupported entries', { cause: error })
  }
  throw error
}

Prevention

When it happens

Trigger: An entry whose path is not classified by isBackupJsonPath, isBackupSessionPath, or isBackupResourcePath reaches the else branch.

Common situations: A backup from a newer format that added new entry kinds; a user zipped extra files into the archive; macOS __MACOSX/ metadata or .DS_Store surviving into the zip.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/91bfdccb741116bd. Report an issue: GitHub.