{"record":{"id":"d53c305a116edad2","repo":"linshenkx/prompt-optimizer","slug":"function-mode-functionmode-cannot-be-empty","errorCode":null,"errorMessage":"Function mode (functionMode) cannot be empty","messagePattern":"Function mode \\(functionMode\\) cannot be empty","errorType":"validation","errorClass":"FavoriteValidationError","httpStatus":null,"severity":"warning","filePath":"packages/core/src/services/favorite/manager.ts","lineNumber":271,"sourceCode":"        // ✅ 标记已初始化\n        await this.storageProvider.setItem('favorite_categories_initialized', 'true');\n      }\n    } catch (error) {\n      console.warn('[FavoriteManager] Failed to ensure default categories:', error);\n    }\n  }\n\n  async addFavorite(favorite: Omit<FavoritePrompt, 'id' | 'createdAt' | 'updatedAt' | 'useCount'>): Promise<string> {\n    await this.ensureInitialized();\n\n    // 验证输入\n    if (!favorite.content?.trim()) {\n      throw new FavoriteValidationError('Prompt content cannot be empty');\n    }\n\n    // 验证 functionMode 必填\n    if (!favorite.functionMode) {\n      throw new FavoriteValidationError('Function mode (functionMode) cannot be empty');\n    }\n\n    // 验证功能模式分类的完整性\n    if (favorite.functionMode === 'basic' || favorite.functionMode === 'context') {\n      if (!favorite.optimizationMode) {\n        throw new FavoriteValidationError(`${favorite.functionMode} mode must specify optimizationMode`);\n      }\n    }\n\n    if (favorite.functionMode === 'image') {\n      if (!favorite.imageSubMode) {\n        throw new FavoriteValidationError('Image mode must specify imageSubMode');\n      }\n    }\n\n    assertFavoriteMetadataHasNoInlineImages(favorite.metadata);\n\n    const favoriteData = {","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/favorite/manager.ts#L253-L289","documentation":"addFavorite rejects with FavoriteValidationError when favorite.functionMode is falsy. Every favorite must declare its function mode (e.g. basic/context/image) so downstream behavior is deterministic.","triggerScenarios":"await manager.addFavorite({ content: 'x' }) with no functionMode — introduced when the functionMode field became mandatory.","commonSituations":"Code written against an older API where functionMode was optional; deserialized records missing the field; form not updated after upgrading the library.","solutions":["Set functionMode explicitly on every favorite you create","Default it in a mapping layer when upgrading old call sites","Catch FavoriteValidationError to find remaining call sites during migration"],"exampleFix":"// before\nawait manager.addFavorite({ content, title });\n// after\nawait manager.addFavorite({ content, title, functionMode: 'basic', optimizationMode: 'standard' });","handlingStrategy":"validation","validationCode":"if (!fav.functionMode) fav = { ...fav, functionMode: 'basic', optimizationMode: 'standard' };","typeGuard":"const hasFunctionMode = (f: Partial<FavoritePrompt>): f is FavoritePrompt & { functionMode: string } => !!f.functionMode;","tryCatchPattern":"try { await manager.addFavorite(fav); } catch (e) { if (e instanceof FavoriteValidationError && /functionMode/.test(e.message)) { fav.functionMode = 'basic'; return manager.addFavorite(fav as any); } throw e; }","preventionTips":["Always construct favorites via a typed builder","Add a compile-time Required check on functionMode at call sites","Grep old call sites when upgrading the library"],"tags":["favorite","validation","required-field","breaking-change"],"backgroundTag":"required-field-missing","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}