{"record":{"id":"cde79b735956bf96","repo":"linshenkx/prompt-optimizer","slug":"data-must-be-an-object","errorCode":null,"errorMessage":"Data must be an object","messagePattern":"Data must be an object","errorType":"validation","errorClass":"DataInvalidFormatError","httpStatus":null,"severity":"warning","filePath":"packages/core/src/services/data/manager.ts","lineNumber":106,"sourceCode":"    const exportFormat = {\n      version: 1,\n      data\n    };\n\n    return JSON.stringify(exportFormat, null, 2); // 格式化输出，便于调试\n  }\n\n  async importAllData(dataString: string): Promise<void> {\n    let exportData: any;\n\n    try {\n      exportData = JSON.parse(dataString);\n    } catch (error) {\n      throw new DataInvalidJsonError(error instanceof Error ? error.message : String(error))\n    }\n\n    if (!exportData || typeof exportData !== 'object' || Array.isArray(exportData)) {\n      throw new DataInvalidFormatError('Data must be an object')\n    }\n\n    // Support both old and new format for backward compatibility\n    let dataToImport: Record<string, any>;\n\n    // New format: { version: 1, data: { ... } }\n    if (exportData.version) {\n      if (!exportData.data || typeof exportData.data !== 'object' || Array.isArray(exportData.data)) {\n        throw new DataInvalidFormatError('\"data\" property is missing or not an object')\n      }\n      dataToImport = exportData.data;\n    }\n    // Old format: direct data object { history: [...], models: [...], ... }\n    else if (exportData.history || exportData.models || exportData.imageModels || exportData.userTemplates || exportData.userSettings || exportData.contexts) {\n      dataToImport = exportData;\n    }\n    else {\n      throw new DataInvalidFormatError('Unrecognized data structure')","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/data/manager.ts#L88-L124","documentation":"OptimizationError thrown by validateMessageOptimizationRequest when request.modelKey is empty in the message-optimization flow — the same missing-model check as validateInput but for optimizeMessage/optimizeMessageStream requests.","triggerScenarios":"Calling optimizeMessage without a model key: no default model configured, model selector not loaded, or the request object built without copying the selected model.","commonSituations":"Fresh install with no model set, settings reset, UI race on initial render, request builders that omit modelKey when refactoring.","solutions":["Populate modelKey from the currently selected/default model before building the request.","Require model configuration on first run before message optimization is available.","Type-check requests against MessageOptimizationRequest to catch omissions at build time.","Surface 'choose a model' guidance when this error is caught."],"exampleFix":"// before\nawait promptService.optimizeMessage({ selectedMessageId: id, messages });\n\n// after\nawait promptService.optimizeMessage({ selectedMessageId: id, messages, modelKey: selectedModel.key });","handlingStrategy":"validation","validationCode":"const modelKey = selectedModel?.key ?? settings.defaultModelKey;\nif (!modelKey?.trim()) throw new Error('Select a model');","typeGuard":"function hasModelKey(k: unknown): k is string { return typeof k === 'string' && k.trim().length > 0; }","tryCatchPattern":"try { await svc.optimizeMessage(req); } catch (e) { if (e instanceof OptimizationError && /Model key/.test(e.message)) promptModelSelection(); }","preventionTips":["Always build requests with the current model selection","Configure a default model on first run","Type-check requests at compile time"],"tags":["validation","model-config","message-optimization"],"backgroundTag":"missing-model-key","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}