{"record":{"id":"ba47c673205dc54d","repo":"linshenkx/prompt-optimizer","slug":"failed-to-parse-llm-response-error-instanceof-e-ba47c6","errorCode":null,"errorMessage":"Failed to parse LLM response: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Failed to parse LLM response: (.+?)","errorType":"exception","errorClass":"VariableValueGenerationParseError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/variable-value-generation/service.ts","lineNumber":186,"sourceCode":"\n    // 1. 尝试提取 JSON 代码块\n    const jsonMatch = textContent.match(/```json\\s*([\\s\\S]*?)\\s*```/i);\n    const jsonText = jsonMatch ? jsonMatch[1] : textContent;\n\n    try {\n      // 2. 使用 jsonrepair 修复可能的格式问题\n      const repaired = jsonrepair(jsonText);\n      const parsed = JSON.parse(repaired);\n\n      // 3. 标准化响应（传递请求的变量列表用于对齐）\n      return this.normalizeGenerationResponse(parsed, requestedVariables);\n    } catch (error) {\n      // 回退：尝试直接解析\n      try {\n        const parsed = JSON.parse(jsonText);\n        return this.normalizeGenerationResponse(parsed, requestedVariables);\n      } catch (fallbackError) {\n        throw new VariableValueGenerationParseError(\n          `Failed to parse LLM response: ${error instanceof Error ? error.message : String(error)}`\n        );\n      }\n    }\n  }\n\n  /**\n   * 标准化并验证生成响应\n   * 🔧 修复：添加变量对齐校验，确保返回的变量与请求一致\n   */\n  private normalizeGenerationResponse(\n    data: any,\n    requestedVariables: VariableToGenerate[]\n  ): VariableValueGenerationResponse {\n    if (!data || typeof data !== 'object') {\n      throw new VariableValueGenerationParseError('Generation result is not a valid object.');\n    }\n","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/variable-value-generation/service.ts#L168-L204","documentation":"parseGenerationResult first tries structured extraction, then falls back to raw JSON.parse on the model's text; if both fail, VariableValueGenerationParseError is thrown carrying the FIRST (structured-extraction) error message. It means the LLM's output is not parseable JSON at all.","triggerScenarios":"generate() receives a model reply like prose (\"Here are the values: ...\"), markdown-fenced JSON handled incorrectly, truncated JSON cut off by max_tokens, or an error page/HTML from the provider instead of JSON.","commonSituations":"Model wraps JSON in ```json fences or adds commentary; max_tokens too small so the JSON is cut mid-string; provider returning an HTML error page that bypasses response checks; weak models ignoring the JSON instruction; temperature too high producing chatty output.","solutions":["Log the raw model output to see exactly why JSON.parse failed","Raise max_tokens so the response is not truncated","Strengthen the template to demand raw JSON only — no markdown fences, no commentary","Strip fences/commentary before parsing if you control the pipeline, or retry once","Switch to a model with reliable JSON-mode/structured-output support"],"exampleFix":"// before\nconst res = await gen.generate(req);\n\n// after\ntry {\n  const res = await gen.generate(req);\n} catch (e) {\n  if (e instanceof VariableValueGenerationParseError) {\n    const res2 = await gen.generate({ ...req, /* raise token budget / stricter template */ });\n    return res2;\n  }\n  throw e;\n}","handlingStrategy":"retry","validationCode":"const looksLikeJson = (t: string) => { const s = t.trim(); return s.startsWith('{') || s.startsWith('['); };","typeGuard":null,"tryCatchPattern":"catch (e) { if (e instanceof VariableValueGenerationParseError) { return gen.generate(req); /* one bounded retry */ } throw e; }","preventionTips":["Set adequate max_tokens and instruct 'raw JSON only, no markdown fences'","Retry once — malformed JSON from LLMs is often stochastic","Log raw model text on parse failure to spot provider error pages"],"tags":["llm-output","json","parse-error","variable-value-generation"],"backgroundTag":"llm-invalid-json-response","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}