{"record":{"id":"49132a1b2f98ccff","repo":"linshenkx/prompt-optimizer","slug":"category-not-found","errorCode":"CATEGORY_NOT_FOUND","errorMessage":"${error.id}","messagePattern":"\\$\\{error\\.id\\}","errorType":"exception","errorClass":"FavoriteCategoryNotFoundError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/favorite/electron-proxy.ts","lineNumber":59,"sourceCode":"    this.ensureApiAvailable();\n    try {\n      const safeArgs = safeSerializeArgs(...args);\n      return await (window.electronAPI.favoriteManager as any)[method](...safeArgs);\n    } catch (error: any) {\n      // New i18n-style structured errors: pass through as-is so UI can translate via `code + params`.\n      if (typeof error?.code === 'string' && error.code.startsWith('error.')) {\n        throw toErrorWithCode(error)\n      }\n\n      // 将IPC错误转换为具体的错误类型\n      if (error.code === 'FAVORITE_NOT_FOUND') {\n        throw new FavoriteNotFoundError(error.id || '');\n      }\n      if (error.code === 'FAVORITE_ALREADY_EXISTS') {\n        throw new FavoriteAlreadyExistsError(error.content || '');\n      }\n      if (error.code === 'CATEGORY_NOT_FOUND') {\n        throw new FavoriteCategoryNotFoundError(error.id || '');\n      }\n      if (error.code === 'VALIDATION_ERROR') {\n        throw new FavoriteValidationError(error.message || '');\n      }\n      if (error.code === 'STORAGE_ERROR') {\n        throw new FavoriteStorageError(error.message || '');\n      }\n      // Legacy: category already exists\n      if (error.code === 'CATEGORY_ALREADY_EXISTS') {\n        throw new FavoriteValidationError(error.message || 'Category already exists')\n      }\n      // 标签相关错误\n      if (error.code === 'TAG_ALREADY_EXISTS') {\n        throw new FavoriteTagAlreadyExistsError(error.tag || '');\n      }\n      if (error.code === 'TAG_NOT_FOUND') {\n        throw new FavoriteTagNotFoundError(error.tag || '');\n      }","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/favorite/electron-proxy.ts#L41-L77","documentation":"Main process returned CATEGORY_NOT_FOUND; converted to FavoriteCategoryNotFoundError carrying the category id. The referenced favorite category does not exist in storage.","triggerScenarios":"addFavorite/updateFavorite with a categoryId that was deleted, or category operations on a stale category id, via the Electron proxy.","commonSituations":"Category deleted in another window while a form was open; stale category list in UI state; default category removed by user; migration dropped old categories.","solutions":["Reload categories and let the user re-pick a valid one","Catch FavoriteCategoryNotFoundError and reset the form's category selection","Verify categoryId is set from a fresh fetch, not hardcoded","Recreate missing categories or map to a fallback category before insert"],"exampleFix":"// before\nawait mgr.addFavorite({ ...fav, categoryId });\n// after\nconst cats = await mgr.getCategories();\nif (!cats.some(c => c.id === categoryId)) categoryId = cats[0]?.id;\nawait mgr.addFavorite({ ...fav, categoryId });","handlingStrategy":"validation","validationCode":"const cats = await mgr.getCategories();\nif (!cats.some(c => c.id === categoryId)) categoryId = cats[0]?.id;","typeGuard":"const isCategoryNotFound = (e: unknown): e is FavoriteCategoryNotFoundError => e instanceof FavoriteCategoryNotFoundError;","tryCatchPattern":"try { await mgr.addFavorite(payload); } catch (e) { if (isCategoryNotFound(e)) { await refreshCategories(); return retryWithFreshCategory(); } throw e; }","preventionTips":["Load categories lazily right before submit","Drop deleted categories from selection state","Handle 'no categories exist' explicitly"],"tags":["favorite","category","not-found","electron"],"backgroundTag":"entity-not-found","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}