{"record":{"id":"ffeda7110894ca41","repo":"linshenkx/prompt-optimizer","slug":"category-already-exists","errorCode":"CATEGORY_ALREADY_EXISTS","errorMessage":"${error.message} || 'Category already exists'","messagePattern":"(.+?) \\|\\| 'Category already exists'","errorType":"validation","errorClass":"FavoriteValidationError","httpStatus":null,"severity":"warning","filePath":"packages/core/src/services/favorite/electron-proxy.ts","lineNumber":69,"sourceCode":"      // 将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      }\n      if (error.code === 'TAG_ERROR') {\n        throw new FavoriteTagError(FAVORITE_ERROR_CODES.TAG_ERROR, error.message || '', { details: error.message || '' });\n      }\n      // 数据迁移和导入导出错误\n      if (error.code === 'MIGRATION_ERROR') {\n        throw new FavoriteMigrationError(error.message || '', error.cause);\n      }\n      if (error.code === 'IMPORT_EXPORT_ERROR') {\n        throw new FavoriteImportExportError(error.message || '', error.cause, error.details);\n      }","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/favorite/electron-proxy.ts#L51-L87","documentation":"Legacy error path: main process returned CATEGORY_ALREADY_EXISTS, converted to FavoriteValidationError (legacy mapping, newer code uses a dedicated category-exists error). Thrown when creating a category whose name/identity already exists.","triggerScenarios":"createCategory with a name that already exists, via the Electron proxy talking to an older main-process version.","commonSituations":"Double-submit of the create-category form; version skew between proxy and main (older main still emits CATEGORY_ALREADY_EXISTS); user retyping an existing category name.","solutions":["Check existing category names before creating (case-insensitively if appropriate)","Disable the submit button while the request is pending","Catch FavoriteValidationError for category creation and check for 'already exists' messaging","Upgrade main+renderer together so the non-legacy error code is used"],"exampleFix":"// before\nawait mgr.createCategory(name);\n// after\nconst exists = (await mgr.getCategories()).some(c => c.name === name);\nif (!exists) await mgr.createCategory(name);","handlingStrategy":"validation","validationCode":"const names = new Set((await mgr.getCategories()).map(c => c.name.toLowerCase()));\nif (!names.has(name.toLowerCase())) await mgr.createCategory(name);","typeGuard":"const isLegacyCategoryExists = (e: unknown) =>\n  e instanceof FavoriteValidationError && /already exists/i.test(e.message);","tryCatchPattern":"try { await mgr.createCategory(name); } catch (e) { if (isLegacyCategoryExists(e)) return; throw e; }","preventionTips":["Check for existing names case-insensitively before create","Debounce duplicate submissions","Upgrade main+renderer together to retire the legacy code"],"tags":["favorite","category","duplicate","legacy"],"backgroundTag":"duplicate-entry-rejected","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}