linshenkx/prompt-optimizer · error · Error

favorites package is missing manifest.json

Error message

favorites package is missing manifest.json

What it means

Thrown by readFavoriteResourcePackage in packages/ui/src/utils/favorite-resource-package.ts after unzipSync when the zip has no entry at MANIFEST_JSON_PATH ('manifest.json'). The manifest is mandatory in the favorites package format, so any archive lacking it is rejected before content parsing. A non-zip input would fail inside unzipSync first, so this means a valid zip without the entry.

Source

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

    manifest,
    missingResourceIds,
  }
}

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 = {

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Verify the uploaded file is a favorites package exported by the app
  2. List zip entries and confirm 'manifest.json' is at the archive root with exact casing
  3. Re-zip with manifest.json at top level, or regenerate via the app's exporter
  4. Pre-validate entries before calling readFavoriteResourcePackage for a better UX

Example fix

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

// after
const entries = Object.keys(unzipSync(bytes))
if (!entries.includes('manifest.json')) {
  throw new Error(`Invalid favorites package; entries: ${entries.join(', ')}`)
}
const pkg = readFavoriteResourcePackage(bytes)
Defensive patterns

Strategy: validation

Validate before calling

import { unzipSync } from 'fflate'

const looksLikeFavoritesPackage = (bytes: Uint8Array): boolean => {
  try {
    return 'manifest.json' in unzipSync(bytes)
  } catch {
    return false
  }
}

Try / catch

try {
  const pkg = readFavoriteResourcePackage(bytes)
} catch (e) {
  if (e instanceof Error && e.message.includes('missing manifest.json')) {
    showFileError('Not a favorites package')
    return
  }
  throw e
}

Prevention

When it happens

Trigger: Passing a zip without a root-level 'manifest.json': wrong file uploaded, manifest nested under a directory, differently-cased entry name, or an archive built by external tooling that doesn't follow the package layout.

Common situations: Users selecting an unrelated zip in the import dialog; re-zipped packages with folder prefixes; zips created on case-sensitive systems with different casing; transferring packages through tools that rewrite entry names.

Related errors


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