chatboxai/chatbox · error

Invalid copilots entry

Error message

Invalid copilots entry

What it means

Thrown when restoring copilots if the staged copilots.json value is not an array. The copilots entry must be an array of CopilotDetail so restoreCopilotResourceKeys can map over it. Propagates after rollback.

Source

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

      options.onProgress?.({
        phase: 'restoring',
        current: resourcePlans.length + index + 1,
        total: resourcePlans.length + manifest.sessions.length,
        label: session.name,
      })
    }

    if (manifest.data.settings) {
      const value = stagedEntries.get(manifest.data.settings.path)?.value
      if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('Invalid settings entry')
      await options.storage.setItemNow(
        BackupStorageKey.Settings,
        restoreSettingsResourceKeys(value as Partial<Settings>, resourceKeyMap)
      )
    }
    if (manifest.data.copilots) {
      const value = stagedEntries.get(manifest.data.copilots.path)?.value
      if (!Array.isArray(value)) throw new Error('Invalid copilots entry')
      await options.storage.setItemNow(
        BackupStorageKey.MyCopilots,
        restoreCopilotResourceKeys(value as CopilotDetail[], resourceKeyMap)
      )
    }
    if (manifest.data.sessionSettings) {
      const value = stagedEntries.get(manifest.data.sessionSettings.path)?.value
      if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('Invalid session settings entry')
      const sessionSettings = value as Record<string, unknown>
      for (const key of [BackupStorageKey.ChatSessionSettings, BackupStorageKey.PictureSessionSettings]) {
        if (key in sessionSettings) await options.storage.setItemNow(key, sessionSettings[key])
      }
    }

    await cleanupTemps()
    return {
      manifest,
      warnings: [...manifest.warnings, ...importWarnings],

View on GitHub (pinned to 81571269ad)

Solutions

  1. Re-export with a compatible version.
  2. Repair copilots.json to be a JSON array.
  3. Drop the copilots descriptor from the manifest to skip copilot restore.

Example fix

// before: non-array copilots aborts import
await importBackupArchive(file, options)
// after: validate the copilots entry shape before importing
if (!Array.isArray(parsedCopilots)) {
  throw new Error('copilots.json must be a JSON array')
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate the copilots entry is an array before importing.
if (!Array.isArray(parsedCopilots)) {
  throw new Error('Invalid copilots entry')
}

Type guard

// Narrows an unknown value to an array - the exact check at line 350.
const isCopilotsEntry = Array.isArray as (value: unknown) => value is unknown[]

Try / catch

try {
  await importBackupArchive(file, options)
} catch (error) {
  if (error instanceof Error && error.message === 'Invalid copilots entry') {
    // Repair copilots.json to a JSON array or drop the copilots descriptor.
    throw new Error('copilots.json is malformed', { cause: error })
  }
  throw error
}

Prevention

When it happens

Trigger: manifest.data.copilots is set, but stagedEntries.get(copilots.path).value is not an array.

Common situations: A hand-edited or corrupted copilots.json; a format change that wraps copilots in an object; a truncated file.

Related errors


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