jlcodes99/cockpit-tools · error
transfer_selection_required
transfer_selection_required
Error message
transfer_selection_required
What it means
createManagedBackup requires a non-empty DataTransferSelection: without at least one platform/account/config selected, exportDataTransferJson would produce an empty or meaningless backup file. hasSelection(params.selection) failed, so the library aborts with transfer_selection_required instead of writing an empty backup.
Source
Thrown at src/services/scheduledBackupService.ts:353
}
export function isAutoBackupDue(settings: AutoBackupSettings, now = new Date()): boolean {
if (!settings.enabled) return false;
const selection = getSelectionFromAutoBackupSettings(settings);
if (!hasSelection(selection)) return false;
const lastBackupAt = normalizeDate(settings.last_backup_at);
if (!lastBackupAt) return true;
return now.getTime() - lastBackupAt.getTime() >= AUTO_BACKUP_INTERVAL_MS;
}
export async function createManagedBackup(params: {
trigger: AutoBackupTrigger;
selection: DataTransferSelection;
retentionDays: number;
markAsLastRun?: boolean;
}): Promise<ManagedBackupResult> {
if (!hasSelection(params.selection)) {
throw new Error('transfer_selection_required');
}
const executedAt = new Date();
const content = await exportDataTransferJson(params.selection);
const fileName = buildManagedBackupFileName(params.selection, params.trigger, executedAt);
const path = await invoke<string>('write_auto_backup_file', {
fileName,
content,
});
const deletedFiles = await cleanupAutoBackupFilesInternal(params.retentionDays);
if (params.markAsLastRun !== false) {
await updateAutoBackupLastRunInternal(executedAt.toISOString());
}
dispatchAutoBackupStateChanged();
return {View on GitHub (pinned to 1ed8b77992)
Solutions
- Populate params.selection with at least one platform/account/config entry before calling createManagedBackup
- Run hasSelection-equivalent validation in the UI and disable the backup action until something is selected
- Re-initialize the persisted selection if an app update wiped it
- Gate the scheduler so auto-backup is skipped (not thrown) when selection is empty
Example fix
// before
await createManagedBackup({ trigger: 'manual', selection: emptySelection, retentionDays: 30 });
// after
if (!hasSelection(emptySelection)) {
console.warn('Nothing selected for backup; skipping');
return;
}
await createManagedBackup({ trigger: 'manual', selection: emptySelection, retentionDays: 30 }); Defensive patterns
Strategy: validation
Validate before calling
const hasSelection = (s: DataTransferSelection) => Boolean(s.platforms?.length || s.accounts?.length || s.includeConfig); if (!hasSelection(params.selection)) return; // skip instead of throwing
Type guard
function selectionIsNonEmpty(s: DataTransferSelection): boolean {
return Object.values(s).some((v) => (Array.isArray(v) ? v.length > 0 : Boolean(v)));
} Try / catch
try {
await createManagedBackup(params);
} catch (e) {
if (e.message === 'transfer_selection_required') {
openSelectionSetupDialog();
} else throw e;
} Prevention
- Validate selection in the UI before enabling the backup button
- Have the scheduler skip empty selections rather than erroring
- Re-check persisted selections after app updates
- Provide first-run defaults so selection is never empty
When it happens
Trigger: Calling createManagedBackup (directly or via the auto-backup scheduler) with a selection where all category flags are false / selected sets are empty — e.g. auto-backup fired when the user deselected everything, or code passed a default-initialized empty selection.
Common situations: Auto-backup trigger running before the user completed first-run selection setup, a persisted selection reset to empty after an app update, or a UI path allowing 'backup' with nothing checked.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- invalid_backup_json
- backup_accounts_missing
- invalidJsonMessage
- messages.noItems
- messages.providerMismatch
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/5ed10968cb5d53c4.
Report an issue: GitHub.