{"record":{"id":"d36a278c5be29016","repo":"linshenkx/prompt-optimizer","slug":"tag-not-found-error-tag","errorCode":null,"errorMessage":"Tag not found: ${error.tag || ''}","messagePattern":"Tag not found: (.+?)","errorType":"exception","errorClass":"FavoriteTagNotFoundError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/favorite/electron-proxy.ts","lineNumber":76,"sourceCode":"      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      }\n      // Fallback: preserve message as details for i18n-friendly error\n      throw new FavoriteError(FAVORITE_ERROR_CODES.STORAGE_ERROR, error.message || 'Unknown error', {\n        details: error.message || 'Unknown error',\n      });\n    }\n  }\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/favorite/electron-proxy.ts#L58-L94","documentation":"Main process returned TAG_NOT_FOUND; the proxy throws FavoriteTagNotFoundError with the tag name. The referenced tag does not exist in the tag store. (Note: the literal message in this code path is the tag name itself; the prefixed 'Tag not found:' form is the canonical message of FavoriteTagNotFoundError.)","triggerScenarios":"updateTag/deleteTag/assignTag operations referencing a tag that was deleted, via the Electron proxy.","commonSituations":"Stale tag list in UI after deletion elsewhere; tag removed during import/migration; race between tag picker refresh and delete.","solutions":["Refresh the tag list and retry with a current tag","Catch FavoriteTagNotFoundError and remove the stale tag from UI selection","Reconcile tag state after any delete/import operation"],"exampleFix":"// before\nawait mgr.deleteTag(tag);\n// after\ntry { await mgr.deleteTag(tag); }\ncatch (e) { if (e instanceof FavoriteTagNotFoundError) return; throw e; }","handlingStrategy":"try-catch","validationCode":"const current = await mgr.getTags();\nconst valid = current.some(t => t.name === tag);","typeGuard":"const isTagNotFound = (e: unknown): e is FavoriteTagNotFoundError => e instanceof FavoriteTagNotFoundError;","tryCatchPattern":"try { await mgr.deleteTag(tag); } catch (e) { if (isTagNotFound(e)) return; throw e; }","preventionTips":["Drop deleted tags from pickers immediately","Reconcile tag state after import/migration","Make tag removal idempotent"],"tags":["favorite","tag","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"}