{"record":{"id":"56f4a6895fcc8e78","repo":"jlcodes99/cockpit-tools","slug":"invalid-bundle-version","errorCode":"invalid_bundle_version","errorMessage":"invalid_bundle_version","messagePattern":"invalid_bundle_version","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/accountTransferService.ts","lineNumber":339,"sourceCode":"}\n\nexport async function exportAllAccountsTransferJson(): Promise<string> {\n  const bundle = await buildAccountTransferBundle();\n  return JSON.stringify(bundle, null, 2);\n}\n\nfunction parseAccountTransferBundle(jsonContent: string): Record<PlatformId, AccountTransferPlatformPayload> {\n  const parsed = parseJsonOrThrow(jsonContent, 'invalid_json');\n  if (!isRecord(parsed)) {\n    throw new Error('invalid_bundle_root');\n  }\n\n  if (parsed.schema !== ACCOUNT_TRANSFER_SCHEMA) {\n    throw new Error('invalid_bundle_schema');\n  }\n\n  if (parsed.version !== ACCOUNT_TRANSFER_VERSION) {\n    throw new Error('invalid_bundle_version');\n  }\n\n  const rawPlatforms = parsed.platforms;\n  if (!isRecord(rawPlatforms)) {\n    throw new Error('invalid_bundle_platforms');\n  }\n\n  const platforms: Record<PlatformId, AccountTransferPlatformPayload> = {} as Record<\n    PlatformId,\n    AccountTransferPlatformPayload\n  >;\n\n  for (const platform of ALL_PLATFORM_IDS) {\n    const resolved = resolvePlatformPayload(rawPlatforms[platform]);\n    platforms[platform] =\n      resolved ??\n      ({\n        account_count: 0,","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/services/accountTransferService.ts#L321-L357","documentation":"The transfer bundle's 'version' field does not equal ACCOUNT_TRANSFER_VERSION, so the importer refuses bundles from incompatible versions. This prevents silently misreading fields whose meaning changed between versions.","triggerScenarios":"parsed.schema matches but parsed.version !== ACCOUNT_TRANSFER_VERSION — older or newer export, missing version key (undefined), or version as a string instead of number.","commonSituations":"Importing a bundle exported by an older app release after a breaking change, hand-written bundles omitting version, JSON produced with \"version\": \"1\" instead of 1.","solutions":["Re-export the bundle with the current application version so version matches ACCOUNT_TRANSFER_VERSION","Upgrade the importing application to a version that accepts the bundle's version","Bump the bundle's version field manually only if the payload format is genuinely unchanged","Add a migration path in code for older versions instead of editing files by hand"],"exampleFix":"// before\n{ \"schema\": \"...\", \"version\": \"1\", ... }\n// after\n{ \"schema\": \"...\", \"version\": 1, ... }  // matches ACCOUNT_TRANSFER_VERSION","handlingStrategy":"validation","validationCode":"const obj = JSON.parse(text);\nif (obj.version !== ACCOUNT_TRANSFER_VERSION) throw new Error('invalid_bundle_version');","typeGuard":"function hasValidVersion(v: Record<string, unknown>, expected: number): boolean {\n  return typeof v.version === 'number' && v.version === expected;\n}","tryCatchPattern":"try {\n  await importBundle(text);\n} catch (e) {\n  if (e instanceof Error && e.message === 'invalid_bundle_version') {\n    alert('Bundle version not supported — update the app or re-export the bundle.');\n  } else throw e;\n}","preventionTips":["Re-export bundles after any application upgrade","Serialize version as a number, never a string","Document breaking version changes and provide migration on import","Check the bundle's version field before importing older archives"],"tags":["versioning","validation","schema"],"backgroundTag":"schema-version-mismatch","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"}