jlcodes99/cockpit-tools · error

backup_accounts_missing

backup_accounts_missing

Error message

backup_accounts_missing

What it means

The backup file parsed as an object, but after unwrapping parsed.accounts the bundle has no platforms record. resolveBackupPlatformPayload requires accountBundle.platforms to be an object keyed by platform id in order to locate the requested platform's payload; without it there is nothing to extract, so it throws backup_accounts_missing.

Source

Thrown at src/services/scheduledBackupService.ts:303

  return deleted;
}

export async function openAutoBackupDir(): Promise<void> {
  await invoke('open_auto_backup_dir');
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function resolveBackupPlatformPayload(jsonContent: string, platform: PlatformId): unknown {
  const parsed = JSON.parse(jsonContent) as unknown;
  if (!isRecord(parsed)) {
    throw new Error('invalid_backup_json');
  }
  const accountBundle = isRecord(parsed.accounts) ? parsed.accounts : parsed;
  if (!isRecord(accountBundle.platforms)) {
    throw new Error('backup_accounts_missing');
  }
  const payload = accountBundle.platforms[platform];
  if (!isRecord(payload)) {
    throw new Error('backup_platform_missing');
  }
  return payload.exported_data ?? payload.data ?? payload.accounts ?? [];
}

export function extractAutoBackupPlatformJson(jsonContent: string, platform: PlatformId): string {
  const payload = resolveBackupPlatformPayload(jsonContent, platform);
  return JSON.stringify(payload, null, 2);
}

export function normalizeAutoBackupPlatforms(
  platforms: AutoBackupPlatformEntry[] | undefined,
): AutoBackupPlatformEntry[] {
  const countByPlatform = new Map<PlatformId, number>();
  for (const item of platforms ?? []) {

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Open the backup file and confirm it contains a platforms object (top-level or under accounts) keyed by platform id
  2. Use a backup file produced by createManagedBackup/exportDataTransferJson rather than a hand-built JSON
  3. Upgrade/downgrade to matching versions if the file came from another app version with a different schema
  4. Pass the full backup file content, not just the accounts sub-object

Example fix

// before: passing only the accounts section
await payload(JSON.stringify(bundle.accounts), 'zed');
// after: pass the whole bundle
if (!bundle.accounts?.platforms) throw new Error('backup has no platforms section');
await payload(JSON.stringify(bundle), 'zed');
Defensive patterns

Strategy: validation

Validate before calling

const bundle = isRecord(parsed.accounts) ? parsed.accounts : parsed;
if (!isRecord(bundle.platforms)) throw new Error('Backup has no platforms section');

Type guard

function hasPlatforms(v: unknown): v is { platforms: Record<string, unknown> } {
  const b = (v as any)?.accounts ?? v;
  return typeof b?.platforms === 'object' && b.platforms !== null && !Array.isArray(b.platforms);
}

Try / catch

try {
  const data = await payload(backupText, platform);
} catch (e) {
  if (e.message === 'backup_accounts_missing') {
    console.error('Backup file lacks platforms map — not a valid auto-backup file');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling payload()/extractAutoBackupPlatformJson with a JSON object that lacks both a top-level platforms object and an accounts.platforms object — e.g. a settings-only export, a manually trimmed backup, or a backup written by an older schema without platforms grouping.

Common situations: Restoring from a hand-edited or partial backup file, importing an export produced by a different tool/version whose bundle shape differs, or passing the inner accounts object to the API instead of the whole file.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/2d4e2bb902be95a7. Report an issue: GitHub.