{"record":{"id":"deb6439d886191cd","repo":"linshenkx/prompt-optimizer","slug":"favorite-entry-exceeds-hard-limit-of-favorite-it","errorCode":null,"errorMessage":"Favorite entry exceeds hard limit of ${FAVORITE_ITEM_HARD_LIMIT_BYTES} bytes","messagePattern":"Favorite entry exceeds hard limit of (.+?) bytes","errorType":"validation","errorClass":"FavoriteValidationError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/favorite/storage-guards.ts","lineNumber":113,"sourceCode":"\n  if (Array.isArray(value)) {\n    value.forEach((item, index) => {\n      assertFavoriteMetadataHasNoInlineImages(item, `${path}[${index}]`, seen)\n    })\n    return\n  }\n\n  Object.entries(value as Record<string, unknown>).forEach(([key, child]) => {\n    assertFavoriteMetadataHasNoInlineImages(child, `${path}.${key}`, seen)\n  })\n}\n\nexport const assertFavoriteFitsItemBudget = (favorite: FavoritePrompt): number => {\n  const serializedFavorite = JSON.stringify(favorite)\n  const itemBytes = getSerializedByteLength(serializedFavorite)\n\n  if (itemBytes > FAVORITE_ITEM_HARD_LIMIT_BYTES) {\n    throw new FavoriteValidationError(\n      `Favorite entry exceeds hard limit of ${FAVORITE_ITEM_HARD_LIMIT_BYTES} bytes`,\n    )\n  }\n\n  return itemBytes\n}\n\nexport const assertFavoritesPayloadWithinBudget = (\n  favorites: FavoritePrompt[],\n  options?: {\n    warnOnSoftLimit?: boolean\n    logWarning?: (message: string) => void\n  },\n): {\n  totalBytes: number\n  softLimitExceeded: boolean\n} => {\n  favorites.forEach((favorite) => {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/favorite/storage-guards.ts#L95-L131","documentation":"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.","triggerScenarios":"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.","commonSituations":"Pasting a huge document as prompt content, embedding large structured data in metadata, or programmatically generated favorites with unbounded content.","solutions":["Trim the prompt content and slim metadata until the serialized favorite fits the limit","Compute the size up front with new TextEncoder().encode(JSON.stringify(favorite)).length before saving","Split oversized prompts into multiple favorites, or move large data out of favorites"],"exampleFix":"// before\nawait manager.addFavorite({ content: hugeDocument, metadata: bigMeta });\n\n// after\nconst item = { content: hugeDocument.slice(0, MAX_LEN), metadata: undefined };\nif (new TextEncoder().encode(JSON.stringify(item)).length <= LIMIT) {\n  await manager.addFavorite(item);\n}","handlingStrategy":"validation","validationCode":"const itemBytes = new TextEncoder().encode(JSON.stringify(favorite)).length;\nif (itemBytes > FAVORITE_ITEM_HARD_LIMIT_BYTES) {\n  favorite = { ...favorite, content: favorite.content.slice(0, TRIMMED_LEN), metadata: undefined };\n}","typeGuard":null,"tryCatchPattern":"try {\n  await manager.addFavorite(fav);\n} catch (e) {\n  if (e instanceof FavoriteValidationError && /entry exceeds hard limit/.test(e.message)) {\n    fav.content = fav.content.slice(0, TRIMMED_LEN);\n    await manager.addFavorite(fav);\n  }\n}","preventionTips":["Measure serialized size with TextEncoder before saving large prompts","Keep metadata minimal; move big data out of favorites","Split oversized prompts into multiple entries"],"tags":["validation","size-limit","storage","favorites"],"backgroundTag":"payload-size-limit-exceeded","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}