{"record":{"id":"eb75f8473faaa7cb","repo":"linshenkx/prompt-optimizer","slug":"invalid-favorites-json-payload","errorCode":null,"errorMessage":"Invalid favorites JSON payload","messagePattern":"Invalid favorites JSON payload","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/utils/favorite-resource-package.ts","lineNumber":103,"sourceCode":"type ImportFavoriteResourcePackageOptions = {\n  favoriteManager: Pick<IFavoriteManager, 'importFavorites'>\n  imageStorageService?: Pick<IImageStorageService, 'getImage' | 'saveImage'> | null\n  mergeStrategy?: 'skip' | 'overwrite' | 'merge'\n}\n\nconst FAVORITES_JSON_PATH = 'favorites.json'\nconst MANIFEST_JSON_PATH = 'manifest.json'\nconst IMAGE_RESOURCE_ROOT = 'resources/images/'\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 parseFavoriteExportJson = (json: string): FavoriteExportJson => {\n  const parsed = JSON.parse(json) as unknown\n  if (!isRecord(parsed) || !Array.isArray(parsed.favorites)) {\n    throw new Error('Invalid favorites JSON payload')\n  }\n  return parsed as FavoriteExportJson\n}\n\nconst parseManifest = (json: string): FavoriteResourcePackageManifest => {\n  const parsed = JSON.parse(json) as unknown\n  if (\n    !isRecord(parsed) ||\n    parsed.schemaVersion !== FAVORITE_RESOURCE_PACKAGE_SCHEMA_VERSION ||\n    !Array.isArray(parsed.resources) ||\n    !Array.isArray(parsed.missingResourceIds)\n  ) {\n    throw new Error('Invalid favorites package manifest')\n  }\n  return parsed as FavoriteResourcePackageManifest\n}\n\nconst getExportStorageCandidates = (","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/utils/favorite-resource-package.ts#L85-L121","documentation":"Thrown by parseFavoriteExportJson in packages/ui/src/utils/favorite-resource-package.ts when the favorites JSON string parses but is not an object containing an array-typed favorites field. This validates the payload consumed by exportData when re-packaging favorites, ensuring the favorites array exists before further processing. A raw JSON.parse SyntaxError is a separate failure that happens before this check.","triggerScenarios":"Calling exportData with a favorites JSON string that is valid JSON but shaped wrong: a JSON array at the top level, an object whose favorites key is missing or is an object/string/number instead of an array, or an empty string edge case parsed into a non-record. It also fires when feed data from a different schema version is passed in.","commonSituations":"Schema drift after a favorites format change; passing the wrong JSON file (e.g. manifest.json or app-data.json instead of the favorites payload); hand-crafted import files; double-stringified JSON that parses to a string.","solutions":["Log/inspect the JSON being passed: it must be an object like {\"favorites\": [...]}","If the payload came from readFavoriteResourcePackage, re-export the favorites package from the source app","Fix the producer to always serialize { favorites: FavoriteJson[] }","Add a type guard (see defense) before calling exportData"],"exampleFix":"// before\nawait exportData({ favoritesJson: manifestJsonString }) // wrong file: throws Invalid favorites JSON payload\n\n// after\nconst parsed = JSON.parse(favoritesJsonString)\nif (!isRecord(parsed) || !Array.isArray(parsed.favorites)) {\n  throw new Error('Favorites file must be an object with a favorites array')\n}\nawait exportData({ favoritesJson: favoritesJsonString })","handlingStrategy":"type-guard","validationCode":"const isFavoriteExportJson = (v: unknown): v is { favorites: unknown[] } =>\n  typeof v === 'object' && v !== null && Array.isArray((v as { favorites?: unknown }).favorites)\n\n// before calling exportData:\nlet parsed: unknown\ntry {\n  parsed = JSON.parse(favoritesJson)\n} catch {\n  throw new Error('Favorites file is not valid JSON')\n}\nif (!isFavoriteExportJson(parsed)) {\n  throw new Error('Favorites file must contain a favorites array')\n}","typeGuard":"const isFavoriteExportJson = (v: unknown): v is FavoriteExportJson =>\n  typeof v === 'object' && v !== null && Array.isArray((v as FavoriteExportJson).favorites)","tryCatchPattern":"try {\n  await exportData({ favoritesJson })\n} catch (e) {\n  if (e instanceof Error && e.message === 'Invalid favorites JSON payload') {\n    // wrong file or schema drift; re-export favorites from source\n    return\n  }\n  throw e\n}","preventionTips":["Always pass the favorites.json payload, not manifest.json or app-data.json","Validate the parsed shape with a type guard before exportData","Pin the favorites schema version between producer and consumer","Never hand-author favorites JSON without the top-level favorites array"],"tags":["json","schema-validation","favorites","payload-validation"],"backgroundTag":"json-payload-validation-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}