linshenkx/prompt-optimizer · error · Error

favorites package is missing favorites.json

Error message

favorites package is missing favorites.json

What it means

Thrown by readFavoriteResourcePackage in packages/ui/src/utils/favorite-resource-package.ts when the zip contains manifest.json but no entry at FAVORITES_JSON_PATH ('favorites.json'). The favorites payload is required alongside the manifest, so the package is rejected. This is the second and last entry-presence check before parseManifest runs on the manifest bytes.

Source

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

}

export const readFavoriteResourcePackage = (
  input: ArrayBuffer | Uint8Array,
): {
  manifest: FavoriteResourcePackageManifest
  favoritesJson: string
  files: Record<string, Uint8Array>
} => {
  const bytes = input instanceof Uint8Array ? input : new Uint8Array(input)
  const files = unzipSync(bytes)
  const manifestBytes = files[MANIFEST_JSON_PATH]
  const favoritesBytes = files[FAVORITES_JSON_PATH]

  if (!manifestBytes) {
    throw new Error('favorites package is missing manifest.json')
  }
  if (!favoritesBytes) {
    throw new Error('favorites package is missing favorites.json')
  }

  return {
    manifest: parseManifest(strFromU8(manifestBytes)),
    favoritesJson: strFromU8(favoritesBytes),
    files,
  }
}

const restoreFavoritePackageResources = async (
  manifest: FavoriteResourcePackageManifest,
  files: Record<string, Uint8Array>,
  imageStorageService: ImportFavoriteResourcePackageOptions['imageStorageService'],
): Promise<FavoriteResourceRestoreReport> => {
  const report: FavoriteResourceRestoreReport = {
    restored: 0,
    skipped: 0,
    missing: [...manifest.missingResourceIds],

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Confirm 'favorites.json' exists at the zip root next to manifest.json
  2. Re-export the favorites package from the source app to get a complete archive
  3. Pre-check required entries before calling readFavoriteResourcePackage
  4. If assembling packages programmatically, always write both manifest.json and favorites.json

Example fix

// before
const pkg = readFavoriteResourcePackage(bytes) // throws: missing favorites.json

// after
const names = Object.keys(unzipSync(bytes))
for (const required of ['manifest.json', 'favorites.json']) {
  if (!names.includes(required)) throw new Error(`Package incomplete: no ${required}`)
}
const pkg = readFavoriteResourcePackage(bytes)
Defensive patterns

Strategy: validation

Validate before calling

import { unzipSync } from 'fflate'

const hasFavoritePayload = (bytes: Uint8Array): boolean => {
  try {
    const entries = Object.keys(unzipSync(bytes))
    return entries.includes('manifest.json') && entries.includes('favorites.json')
  } catch {
    return false
  }
}

Try / catch

try {
  const pkg = readFavoriteResourcePackage(bytes)
} catch (e) {
  if (e instanceof Error && e.message.includes('missing favorites.json')) {
    // incomplete package: re-export rather than restore
    return
  }
  throw e
}

Prevention

When it happens

Trigger: A zip with manifest.json but without a root-level favorites.json entry: partial/interrupted export, manual removal or renaming of the payload, or a manifest-only template archive passed to the reader.

Common situations: Interrupted exports producing incomplete archives; users pruning files from the zip; repackaging pipelines that drop JSON payloads; casing differences from zip tools on case-sensitive systems.

Related errors


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