{"record":{"id":"55f39161668de088","repo":"linshenkx/prompt-optimizer","slug":"extraction-result-is-not-a-valid-object","errorCode":null,"errorMessage":"Extraction result is not a valid object.","messagePattern":"Extraction result is not a valid object\\.","errorType":"validation","errorClass":"VariableExtractionParseError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/variable-extraction/service.ts","lineNumber":194,"sourceCode":"\n      // 尝试直接解析（不通过 jsonrepair）\n      try {\n        const parsed = JSON.parse(jsonText);\n        return this.normalizeExtractionResponse(parsed);\n      } catch (fallbackError) {\n        throw new VariableExtractionParseError(\n          `Failed to parse LLM response: ${error instanceof Error ? error.message : String(error)}. Raw content length: ${content.length} characters.`\n        );\n      }\n    }\n  }\n\n  /**\n   * 标准化提取响应（统一结构）\n   */\n  private normalizeExtractionResponse(data: any): VariableExtractionResponse {\n    if (!data || typeof data !== 'object') {\n      throw new VariableExtractionParseError('Extraction result is not a valid object.');\n    }\n\n    // 验证 variables 字段\n    if (!Array.isArray(data.variables)) {\n      throw new VariableExtractionParseError('Extraction result must have a \"variables\" array.');\n    }\n\n    // 验证 summary 字段\n    if (typeof data.summary !== 'string') {\n      throw new VariableExtractionParseError('Extraction result must have a \"summary\" string.');\n    }\n\n    // 标准化每个变量\n    const variables: ExtractedVariable[] = data.variables.map((variable: any, index: number) => {\n      // 验证必需字段\n      if (!variable || typeof variable !== 'object') {\n        throw new VariableExtractionParseError(`variables[${index}] is not a valid object.`);\n      }","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/variable-extraction/service.ts#L176-L212","documentation":"The LLM response was parsed to a value, but that value is not an object (null, array, string, number, or boolean). The extraction contract requires a top-level JSON object with variables and summary, so normalization aborts immediately.","triggerScenarios":"Model returns a bare JSON array of variables, a quoted string, a number, or literal null instead of an object. Reached via extract() whenever parseExtractionResult succeeds on a non-object JSON payload.","commonSituations":"Prompt asks for 'a list of variables' so the model returns [...] instead of {\"variables\": [...]}; model returns the string 'null' or an empty response coerced to null; template output-format instruction drifted from the unified schema.","solutions":["Fix the prompt/template to explicitly require an object like {\"variables\": [...], \"summary\": \"...\"}.","Log the parsed value (typeof + preview) to see which non-object shape the model emits.","If the model consistently returns an array, add a shim that wraps it: Array.isArray(parsed) ? { variables: parsed } : parsed.","Use a stronger model with better instruction-following for extraction."],"exampleFix":"// before\nreturn this.normalizeExtractionResponse(parsed);\n\n// after\nreturn this.normalizeExtractionResponse(Array.isArray(parsed) ? { variables: parsed, summary: '' } : parsed);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"const isExtractionObject = (d: unknown): d is Record<string, unknown> =>\n  !!d && typeof d === 'object' && !Array.isArray(d);","tryCatchPattern":"try {\n  await extractionService.extract({ modelKey, content });\n} catch (e) {\n  if (e instanceof VariableExtractionParseError && /not a valid object/.test(e.message)) {\n    // model returned array/primitive: fix prompt schema or wrap arrays\n  }\n  throw e;\n}","preventionTips":["Include a concrete few-shot example of {\"variables\":[...],\"summary\":\"...\"} in the prompt.","If you control pre/post-processing, wrap bare arrays before handing off to the service.","Log raw model outputs during development to catch schema drift early."],"tags":["llm","json","schema","normalization"],"backgroundTag":"llm-response-schema-mismatch","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}