linshenkx/prompt-optimizer · warning · FavoriteTagAlreadyExistsError
TAG_ALREADY_EXISTS
TAG_ALREADY_EXISTS
Error message
${error.tag} What it means
Main process returned TAG_ALREADY_EXISTS; converted to FavoriteTagAlreadyExistsError carrying the tag name. Creating a tag that already exists is rejected.
Source
Thrown at packages/core/src/services/favorite/electron-proxy.ts:73
if (error.code === 'FAVORITE_ALREADY_EXISTS') {
throw new FavoriteAlreadyExistsError(error.content || '');
}
if (error.code === 'CATEGORY_NOT_FOUND') {
throw new FavoriteCategoryNotFoundError(error.id || '');
}
if (error.code === 'VALIDATION_ERROR') {
throw new FavoriteValidationError(error.message || '');
}
if (error.code === 'STORAGE_ERROR') {
throw new FavoriteStorageError(error.message || '');
}
// Legacy: category already exists
if (error.code === 'CATEGORY_ALREADY_EXISTS') {
throw new FavoriteValidationError(error.message || 'Category already exists')
}
// 标签相关错误
if (error.code === 'TAG_ALREADY_EXISTS') {
throw new FavoriteTagAlreadyExistsError(error.tag || '');
}
if (error.code === 'TAG_NOT_FOUND') {
throw new FavoriteTagNotFoundError(error.tag || '');
}
if (error.code === 'TAG_ERROR') {
throw new FavoriteTagError(FAVORITE_ERROR_CODES.TAG_ERROR, error.message || '', { details: error.message || '' });
}
// 数据迁移和导入导出错误
if (error.code === 'MIGRATION_ERROR') {
throw new FavoriteMigrationError(error.message || '', error.cause);
}
if (error.code === 'IMPORT_EXPORT_ERROR') {
throw new FavoriteImportExportError(error.message || '', error.cause, error.details);
}
// Fallback: preserve message as details for i18n-friendly error
throw new FavoriteError(FAVORITE_ERROR_CODES.STORAGE_ERROR, error.message || 'Unknown error', {
details: error.message || 'Unknown error',
});View on GitHub (pinned to 3e677b1d9f)
Solutions
- Fetch existing tags and skip creation when the name matches
- Catch FavoriteTagAlreadyExistsError and treat as success (idempotent create)
- Trim/normalize tag names before comparing
- Debounce duplicate create requests
Example fix
// before
await mgr.createTag(tag);
// after
try { await mgr.createTag(tag); }
catch (e) { if (!(e instanceof FavoriteTagAlreadyExistsError)) throw e; } Defensive patterns
Strategy: try-catch
Validate before calling
const tags = new Set((await mgr.getTags?.() ?? []).map(t => t.name)); if (!tags.has(tag)) await mgr.createTag(tag);
Type guard
const isTagAlreadyExists = (e: unknown): e is FavoriteTagAlreadyExistsError => e instanceof FavoriteTagAlreadyExistsError;
Try / catch
try { await mgr.createTag(tag); } catch (e) { if (isTagAlreadyExists(e)) return; throw e; } Prevention
- Treat tag creation as idempotent
- Normalize/trim tag names before compare
- Refresh tag lists after concurrent edits
When it happens
Trigger: createTag/addTags with a tag name already present in the tag store, via the Electron proxy.
Common situations: Concurrent tag creation from two windows; import containing existing tags; UI not deduping user input against the current tag list.
Related errors
- FAVORITE_ALREADY_EXISTS
- Tag not found: ${error.tag || ''}
- TAG_ERROR
- FAVORITE_NOT_FOUND
- CATEGORY_NOT_FOUND
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/84dba727fe79c50c.
Report an issue: GitHub.