linshenkx/prompt-optimizer · error · FavoriteValidationError

Favorite entry exceeds hard limit of ${FAVORITE_ITEM_HARD_LI

Error message

Favorite entry exceeds hard limit of ${FAVORITE_ITEM_HARD_LIMIT_BYTES} bytes

What it means

Per-item storage guard (assertFavoriteFitsItemBudget): JSON.stringify(favorite) must not exceed FAVORITE_ITEM_HARD_LIMIT_BYTES. It runs after the inline-image metadata check within assertFavoritesPayloadWithinBudget, and also from normalizeFavoriteRecord.

Source

Thrown at packages/core/src/services/favorite/storage-guards.ts:113

  if (Array.isArray(value)) {
    value.forEach((item, index) => {
      assertFavoriteMetadataHasNoInlineImages(item, `${path}[${index}]`, seen)
    })
    return
  }

  Object.entries(value as Record<string, unknown>).forEach(([key, child]) => {
    assertFavoriteMetadataHasNoInlineImages(child, `${path}.${key}`, seen)
  })
}

export const assertFavoriteFitsItemBudget = (favorite: FavoritePrompt): number => {
  const serializedFavorite = JSON.stringify(favorite)
  const itemBytes = getSerializedByteLength(serializedFavorite)

  if (itemBytes > FAVORITE_ITEM_HARD_LIMIT_BYTES) {
    throw new FavoriteValidationError(
      `Favorite entry exceeds hard limit of ${FAVORITE_ITEM_HARD_LIMIT_BYTES} bytes`,
    )
  }

  return itemBytes
}

export const assertFavoritesPayloadWithinBudget = (
  favorites: FavoritePrompt[],
  options?: {
    warnOnSoftLimit?: boolean
    logWarning?: (message: string) => void
  },
): {
  totalBytes: number
  softLimitExceeded: boolean
} => {
  favorites.forEach((favorite) => {

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Trim the prompt content and slim metadata until the serialized favorite fits the limit
  2. Compute the size up front with new TextEncoder().encode(JSON.stringify(favorite)).length before saving
  3. Split oversized prompts into multiple favorites, or move large data out of favorites

Example fix

// before
await manager.addFavorite({ content: hugeDocument, metadata: bigMeta });

// after
const item = { content: hugeDocument.slice(0, MAX_LEN), metadata: undefined };
if (new TextEncoder().encode(JSON.stringify(item)).length <= LIMIT) {
  await manager.addFavorite(item);
}
Defensive patterns

Strategy: validation

Validate before calling

const itemBytes = new TextEncoder().encode(JSON.stringify(favorite)).length;
if (itemBytes > FAVORITE_ITEM_HARD_LIMIT_BYTES) {
  favorite = { ...favorite, content: favorite.content.slice(0, TRIMMED_LEN), metadata: undefined };
}

Try / catch

try {
  await manager.addFavorite(fav);
} catch (e) {
  if (e instanceof FavoriteValidationError && /entry exceeds hard limit/.test(e.message)) {
    fav.content = fav.content.slice(0, TRIMMED_LEN);
    await manager.addFavorite(fav);
  }
}

Prevention

When it happens

Trigger: Saving or normalizing a single favorite whose serialized size (content + metadata + all fields) crosses FAVORITE_ITEM_HARD_LIMIT_BYTES — typically a very long prompt or bulky metadata.

Common situations: Pasting a huge document as prompt content, embedding large structured data in metadata, or programmatically generated favorites with unbounded content.

Related errors


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