linshenkx/prompt-optimizer · error · Error

Invalid favorites JSON payload

Error message

Invalid favorites JSON payload

What it means

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.

Source

Thrown at packages/ui/src/utils/favorite-resource-package.ts:103

type ImportFavoriteResourcePackageOptions = {
  favoriteManager: Pick<IFavoriteManager, 'importFavorites'>
  imageStorageService?: Pick<IImageStorageService, 'getImage' | 'saveImage'> | null
  mergeStrategy?: 'skip' | 'overwrite' | 'merge'
}

const FAVORITES_JSON_PATH = 'favorites.json'
const MANIFEST_JSON_PATH = 'manifest.json'
const IMAGE_RESOURCE_ROOT = 'resources/images/'

const isRecord = (value: unknown): value is Record<string, unknown> =>
  !!value && typeof value === 'object' && !Array.isArray(value)

const textToZipBytes = (text: string): Uint8Array => copyBytes(strToU8(text))

const parseFavoriteExportJson = (json: string): FavoriteExportJson => {
  const parsed = JSON.parse(json) as unknown
  if (!isRecord(parsed) || !Array.isArray(parsed.favorites)) {
    throw new Error('Invalid favorites JSON payload')
  }
  return parsed as FavoriteExportJson
}

const parseManifest = (json: string): FavoriteResourcePackageManifest => {
  const parsed = JSON.parse(json) as unknown
  if (
    !isRecord(parsed) ||
    parsed.schemaVersion !== FAVORITE_RESOURCE_PACKAGE_SCHEMA_VERSION ||
    !Array.isArray(parsed.resources) ||
    !Array.isArray(parsed.missingResourceIds)
  ) {
    throw new Error('Invalid favorites package manifest')
  }
  return parsed as FavoriteResourcePackageManifest
}

const getExportStorageCandidates = (

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Log/inspect the JSON being passed: it must be an object like {"favorites": [...]}
  2. If the payload came from readFavoriteResourcePackage, re-export the favorites package from the source app
  3. Fix the producer to always serialize { favorites: FavoriteJson[] }
  4. Add a type guard (see defense) before calling exportData

Example fix

// before
await exportData({ favoritesJson: manifestJsonString }) // wrong file: throws Invalid favorites JSON payload

// after
const parsed = JSON.parse(favoritesJsonString)
if (!isRecord(parsed) || !Array.isArray(parsed.favorites)) {
  throw new Error('Favorites file must be an object with a favorites array')
}
await exportData({ favoritesJson: favoritesJsonString })
Defensive patterns

Strategy: type-guard

Validate before calling

const isFavoriteExportJson = (v: unknown): v is { favorites: unknown[] } =>
  typeof v === 'object' && v !== null && Array.isArray((v as { favorites?: unknown }).favorites)

// before calling exportData:
let parsed: unknown
try {
  parsed = JSON.parse(favoritesJson)
} catch {
  throw new Error('Favorites file is not valid JSON')
}
if (!isFavoriteExportJson(parsed)) {
  throw new Error('Favorites file must contain a favorites array')
}

Type guard

const isFavoriteExportJson = (v: unknown): v is FavoriteExportJson =>
  typeof v === 'object' && v !== null && Array.isArray((v as FavoriteExportJson).favorites)

Try / catch

try {
  await exportData({ favoritesJson })
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid favorites JSON payload') {
    // wrong file or schema drift; re-export favorites from source
    return
  }
  throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/eb75f8473faaa7cb. Report an issue: GitHub.