linshenkx/prompt-optimizer · error · VariableExtractionParseError
variables[${index}] is missing a valid "position" object.
Error message
variables[${index}] is missing a valid "position" object. What it means
Thrown by normalizeExtractionResponse in the variable-extraction service when a variable in the LLM's extraction response is missing its position object or position is not an object. The service strictly validates the LLM's JSON output shape before returning it, because position data (originalText + occurrence) is required to locate the variable inside the prompt. Any deviation from the expected schema raises VariableExtractionParseError.
Source
Thrown at packages/core/src/services/variable-extraction/service.ts:223
}
// 标准化每个变量
const variables: ExtractedVariable[] = data.variables.map((variable: any, index: number) => {
// 验证必需字段
if (!variable || typeof variable !== 'object') {
throw new VariableExtractionParseError(`variables[${index}] is not a valid object.`);
}
if (typeof variable.name !== 'string' || !variable.name.trim()) {
throw new VariableExtractionParseError(`variables[${index}] is missing a valid "name" field.`);
}
if (typeof variable.value !== 'string') {
throw new VariableExtractionParseError(`variables[${index}] is missing a valid "value" field.`);
}
if (!variable.position || typeof variable.position !== 'object') {
throw new VariableExtractionParseError(`variables[${index}] is missing a valid "position" object.`);
}
if (typeof variable.position.originalText !== 'string') {
throw new VariableExtractionParseError(
`variables[${index}].position is missing a valid "originalText" field.`
);
}
if (typeof variable.position.occurrence !== 'number') {
throw new VariableExtractionParseError(
`variables[${index}].position is missing a valid "occurrence" number.`
);
}
if (typeof variable.reason !== 'string') {
throw new VariableExtractionParseError(`variables[${index}] is missing a valid "reason" field.`);
}
View on GitHub (pinned to 3e677b1d9f)
Solutions
- Inspect the raw LLM response logged before normalization to see what shape 'position' actually has
- Tighten the extraction prompt/template to explicitly require {"position": {"originalText": "...", "occurrence": N}} for every variable
- Use a stronger model or lower temperature so the JSON schema is followed more reliably
- Catch VariableExtractionParseError and retry generation once before failing
- If you control the response, pre-validate/repair the payload before passing it to parseExtractionResult
Example fix
// before
const result = await extractionService.parseExtractionResult(rawLlmText);
// after
const parsed = JSON.parse(rawLlmText);
for (const v of parsed.variables ?? []) {
if (!v.position || typeof v.position !== 'object') {
throw new Error(`missing position for variable ${v.name}`); // or repair: v.position = { originalText: v.value, occurrence: 0 }
}
}
const result = await extractionService.parseExtractionResult(rawLlmText); Defensive patterns
Strategy: type-guard
Validate before calling
const ok = (parsed.variables ?? []).every(v => v.position && typeof v.position === 'object' && !Array.isArray(v.position));
Type guard
function hasValidPosition(v: any): v is { name: string; position: Record<string, unknown> } {
return !!v && typeof v === 'object' && !!v.position && typeof v.position === 'object' && !Array.isArray(v.position);
} Try / catch
try { const r = service.parseExtractionResult(text); } catch (e) { if (e instanceof VariableExtractionParseError && /position/.test(e.message)) { /* re-prompt or repair */ } else throw e; } Prevention
- Include a complete one-shot example of the variables array (with position.originalText and position.occurrence) in the extraction prompt
- Log raw LLM output when parse errors spike to catch schema drift early
When it happens
Trigger: Calling parseExtractionResult with an LLM response where variables[i] has no 'position' key, position is null/undefined, or position is a string/number instead of an object (e.g. the model returned "position": "paragraph 2").
Common situations: Weaker LLM models omitting nested objects; prompt template drift after a version upgrade changing the output schema; the model wrapping position differently (e.g. position: { location: {...} }); truncated JSON from max_tokens limits.
Related errors
- variables[${index}].position is missing a valid "originalTex
- variables[${index}] is missing a valid "reason" field.
- variables[${index}].position is missing a valid "occurrence"
- Generation result is not a valid object.
- Generation result must have a "values" array.
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/2850ea1750c569d5.
Report an issue: GitHub.