{"record":{"id":"a121d5b84cbf3afe","repo":"jlcodes99/cockpit-tools","slug":"transfer-selection-required","errorCode":"transfer_selection_required","errorMessage":"transfer_selection_required","messagePattern":"transfer_selection_required","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/dataTransferService.ts","lineNumber":397,"sourceCode":"    return JSON.parse(value);\n  } catch {\n    return value;\n  }\n}\n\nfunction safeSetLocalStorageItem(key: string, value: unknown): void {\n  if (value === null || value === undefined) {\n    localStorage.removeItem(key);\n  } else if (typeof value === 'string') {\n    localStorage.setItem(key, value);\n  } else {\n    localStorage.setItem(key, JSON.stringify(value));\n  }\n}\n\nfunction ensureSelection(selection: DataTransferSelection): void {\n  if (!selection.includeAccounts && !selection.includeConfig) {\n    throw new Error('transfer_selection_required');\n  }\n}\n\nfunction firstLegacySample(value: unknown): Record<string, unknown> | null {\n  if (Array.isArray(value)) {\n    return value.find((item) => isRecord(item)) ?? null;\n  }\n  return isRecord(value) ? value : null;\n}\n\nfunction isDataTransferBundle(value: unknown): value is DataTransferBundle {\n  return isRecord(value) && value.schema === DATA_TRANSFER_SCHEMA;\n}\n\nfunction isAccountTransferBundleLike(value: unknown): boolean {\n  return isRecord(value) && value.schema === ACCOUNT_TRANSFER_SCHEMA;\n}\n","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/services/dataTransferService.ts#L379-L415","documentation":"ensureSelection rejects transfer selections that include nothing: both includeAccounts and includeConfig are false. Export/import functions require at least one data section to operate on. This is a guard against meaningless no-op transfers.","triggerScenarios":"Calling exportDataTransferJson or importDataTransferJson with { includeAccounts: false, includeConfig: false } (or omitting both flags so they default to false); constructing options programmatically and forgetting to set either flag.","commonSituations":"UI form where the user unchecked every checkbox; defaults object built without the flags; conditional logic that disabled both sections after validation.","solutions":["Set includeAccounts: true, includeConfig: true, or both in the options object.","Check selection UI state before calling and disable the submit button when nothing is selected.","Verify you are passing options as the options parameter, not in a nested/wrong field."],"exampleFix":"// before\nawait exportDataTransferJson({ includeAccounts: false, includeConfig: false });\n// after\nawait exportDataTransferJson({ includeAccounts: true, includeConfig: true });","handlingStrategy":"validation","validationCode":"function selectionIsValid(sel) {\n  return Boolean(sel && (sel.includeAccounts || sel.includeConfig));\n}\nif (!selectionIsValid(options)) { alert('Select at least one section (accounts or config).'); return; }","typeGuard":null,"tryCatchPattern":"try {\n  await exportDataTransferJson(options);\n} catch (e) {\n  if (e.message === 'transfer_selection_required') {\n    console.error('Nothing selected: enable includeAccounts and/or includeConfig.');\n  } else throw e;\n}","preventionTips":["Disable the export/import button until at least one checkbox is checked.","Give options explicit true/false values instead of relying on undefined defaults.","Centralize the selection check in one helper used by both export and import paths."],"tags":["validation","options","data-transfer"],"backgroundTag":"empty-selection","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}