{"record":{"id":"9e04e2746bcfb7d1","repo":"linshenkx/prompt-optimizer","slug":"invalid-app-backup-package-manifest","errorCode":null,"errorMessage":"Invalid app backup package manifest","messagePattern":"Invalid app backup package manifest","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/utils/data-manager-resource-package.ts","lineNumber":160,"sourceCode":"  ]\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n  !!value && typeof value === 'object' && !Array.isArray(value)\n\nconst textToZipBytes = (text: string): Uint8Array => copyBytes(strToU8(text))\n\nconst parseManifest = (json: string): DataManagerResourcePackageManifest => {\n  const parsed = JSON.parse(json) as unknown\n  if (\n    !isRecord(parsed) ||\n    parsed.schemaVersion !== DATA_MANAGER_RESOURCE_PACKAGE_SCHEMA_VERSION ||\n    parsed.appDataPath !== APP_DATA_JSON_PATH ||\n    parsed.favoritesPath !== FAVORITES_JSON_PATH ||\n    !Array.isArray(parsed.resources) ||\n    !Array.isArray(parsed.missingResources)\n  ) {\n    throw new Error('Invalid app backup package manifest')\n  }\n  return parsed as DataManagerResourcePackageManifest\n}\n\nconst collectStoreResources = async (\n  config: ImageStoreExportConfig,\n  files: Record<string, Uint8Array>,\n): Promise<{\n  resources: DataManagerResourceManifestEntry[]\n  missing: Array<{ store: DataManagerImageStoreKey; id: string }>\n}> => {\n  if (!config.service) {\n    return { resources: [], missing: [] }\n  }\n\n  const metadataList = await config.service.listAllMetadata()\n  const resources: DataManagerResourceManifestEntry[] = []\n  const missing: Array<{ store: DataManagerImageStoreKey; id: string }> = []","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/utils/data-manager-resource-package.ts#L142-L178","documentation":"Thrown by parseManifest (called from readDataManagerResourcePackage in packages/ui/src/utils/data-manager-resource-package.ts) when the unzipped backup's manifest.json fails structural validation: schemaVersion must equal DATA_MANAGER_RESOURCE_PACKAGE_SCHEMA_VERSION, appDataPath must equal APP_DATA_JSON_PATH, favoritesPath must equal FAVORITES_JSON_PATH, and resources/missingResources must be arrays. It means the zip is not a valid app backup package produced by this code's exporter. It protects the restore path from partially written or foreign archives.","triggerScenarios":"Calling readDataManagerResourcePackage on a zip whose manifest.json has a mismatched schemaVersion (package written by an older/newer app version), wrong appDataPath/favoritesPath values, or missing/non-array resources or missingResources fields. Also triggered by a hand-edited or truncated manifest.json, or JSON.parse succeeding but yielding a non-record (e.g. an array or string).","commonSituations":"Restoring a backup created by a different app version after a schema migration; renaming the internal app-data.json/favorites.json files inside the zip; passing a generic zip that happens to contain a manifest.json; corrupting the manifest during download/transfer. Note JSON.parse failures throw a SyntaxError before this check, so this error specifically means parseable-but-invalid content.","solutions":["Verify the package was exported by the same app version (or a version sharing the same DATA_MANAGER_RESOURCE_PACKAGE_SCHEMA_VERSION); re-export the backup from the source app","Unzip the archive and inspect manifest.json: confirm schemaVersion, appDataPath and favoritesPath values and that resources/missingResources are arrays","If you maintain the exporter, regenerate the package rather than hand-editing the manifest","If supporting cross-version restores, add a migration step that upgrades older manifests to the current schemaVersion before validation"],"exampleFix":"// before\nconst pkg = readDataManagerResourcePackage(bytes) // throws: Invalid app backup package manifest\n\n// after\nconst manifest = JSON.parse(strFromU8(unzipSync(bytes)['manifest.json']))\nif (manifest.schemaVersion !== DATA_MANAGER_RESOURCE_PACKAGE_SCHEMA_VERSION) {\n  throw new Error(`Unsupported backup schema version: ${manifest.schemaVersion}`)\n}\nconst pkg = readDataManagerResourcePackage(bytes)","handlingStrategy":"validation","validationCode":"import { unzipSync } from 'fflate'\nimport { strFromU8 } from 'fflate'\n\nconst isValidAppBackupManifest = (json: string): boolean => {\n  try {\n    const m = JSON.parse(json)\n    return (\n      typeof m === 'object' && m !== null &&\n      m.schemaVersion === DATA_MANAGER_RESOURCE_PACKAGE_SCHEMA_VERSION &&\n      m.appDataPath === 'app-data.json' &&\n      m.favoritesPath === 'favorites.json' &&\n      Array.isArray(m.resources) &&\n      Array.isArray(m.missingResources)\n    )\n  } catch {\n    return false\n  }\n}\n\n// before readDataManagerResourcePackage:\nconst files = unzipSync(bytes)\nconst ok = !!files['manifest.json'] && isValidAppBackupManifest(strFromU8(files['manifest.json']))","typeGuard":"const isAppBackupManifest = (v: unknown): v is DataManagerResourcePackageManifest =>\n  typeof v === 'object' && v !== null &&\n  (v as DataManagerResourcePackageManifest).schemaVersion === DATA_MANAGER_RESOURCE_PACKAGE_SCHEMA_VERSION &&\n  Array.isArray((v as DataManagerResourcePackageManifest).resources) &&\n  Array.isArray((v as DataManagerResourcePackageManifest).missingResources)","tryCatchPattern":"try {\n  const pkg = readDataManagerResourcePackage(bytes)\n} catch (e) {\n  if (e instanceof Error && e.message === 'Invalid app backup package manifest') {\n    // show 'incompatible or corrupted backup' UI; do not retry\n    return\n  }\n  throw e\n}","preventionTips":["Only feed packages exported by the same app version into readDataManagerResourcePackage","Validate the manifest's schemaVersion before restore and surface a version-mismatch message","Never hand-edit manifest fields inside exported packages","Keep a migration layer when bumping DATA_MANAGER_RESOURCE_PACKAGE_SCHEMA_VERSION"],"tags":["zip","manifest","schema-validation","backup-restore"],"backgroundTag":"package-manifest-validation-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}