{"record":{"id":"d0cd65e8d3ac81a0","repo":"linshenkx/prompt-optimizer","slug":"context-error-codes-storage-error","errorCode":"CONTEXT_ERROR_CODES.STORAGE_ERROR","errorMessage":"Failed to parse context store: ${details}","messagePattern":"Failed to parse context store: (.+?)","errorType":"error_code","errorClass":"ContextError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/context/repo.ts","lineNumber":176,"sourceCode":"          console.log('[ContextRepo] Migrated contexts to add mode field');\n        }\n      }\n\n      // 确保currentId对应的上下文存在\n      if (!doc.contexts[doc.currentId]) {\n        // 修复：选择第一个可用的上下文\n        const availableIds = Object.keys(doc.contexts);\n        if (availableIds.length > 0) {\n          doc.currentId = availableIds[0];\n        } else {\n          throw new ContextError(CONTEXT_ERROR_CODES.INVALID_STORE, 'No contexts available');\n        }\n      }\n\n      return doc;\n    } catch (error) {\n      const details = error instanceof Error ? error.message : String(error)\n      throw new ContextError(\n        CONTEXT_ERROR_CODES.STORAGE_ERROR,\n        `Failed to parse context store: ${details}`,\n        { details },\n      );\n    }\n  }\n\n  /**\n   * 更新存储文档\n   */\n  private async updateStoreDoc(\n    updater: (doc: ContextStoreDoc) => ContextStoreDoc\n  ): Promise<ContextStoreDoc> {\n    let updatedDoc: ContextStoreDoc;\n\n    await this.storage.updateData<ContextStoreDoc>(\n      CONTEXT_STORE_KEY,\n      (currentDoc: ContextStoreDoc | null) => {","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/context/repo.ts#L158-L194","documentation":"SmartVariableExtractor.extractVariable validates the proposed variable name against its naming rules (isValidVariableName) before doing anything, and throws with the offending name embedded. Variable names must satisfy the extractor's pattern (typically letters/digits/underscore, no spaces or braces) so the {{placeholder}} substitution stays parseable.","triggerScenarios":"Calling extractVariable('my var', ...) or extractVariable('{{x}}', ...) or an empty name — any name failing the internal naming-rule check.","commonSituations":"Passing raw user input from a text field straight into extractVariable; names with spaces, CJK punctuation, hyphens, or braces; empty input from an unvalidated dialog.","solutions":["Sanitize/validate the name in the UI before calling extractVariable (e.g. /^[A-Za-z_][A-Za-z0-9_]*$/)","Trim and reject empty names; auto-slugify names containing spaces","Show inline validation feedback in the variable-name input field"],"exampleFix":"// before\nconst result = extractor.extractVariable('my variable', content, selectedText, start, end)\n\n// after\nconst safeName = userInput.trim().replace(/\\s+/g, '_')\nif (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(safeName)) {\n  throw new Error(`Invalid variable name: ${userInput}`)\n}\nconst result = extractor.extractVariable(safeName, content, selectedText, start, end)","handlingStrategy":"validation","validationCode":"const VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$//\nif (!VARIABLE_NAME_RE.test(variableName.trim())) {\n  // reject before calling extractVariable\n  throw new Error('Please use letters, digits and underscores only')\n}","typeGuard":"function isValidVariableName(name: string): boolean {\n  return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name)\n}","tryCatchPattern":"try {\n  const result = extractor.extractVariable(name, content, selectedText, start, end)\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith('Invalid variable name:')) {\n  showInlineError(error.message)\n  return\n  }\n  throw error\n}","preventionTips":["Validate in the UI input field as the user types","Auto-slugify names (replace spaces with underscores)","Never pass raw template text or {{...}} strings as names"],"tags":["validation","user-input","variable-naming"],"backgroundTag":"input-validation-failed","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}