linshenkx/prompt-optimizer · error · VariableExtractionParseError

variables[${index}].position is missing a valid "originalTex

Error message

variables[${index}].position is missing a valid "originalText" field.

What it means

Thrown by normalizeExtractionResponse when a variable's position object exists but lacks a string originalText field. originalText is needed to disambiguate which occurrence of a substring in the prompt the variable refers to, so the service refuses to normalize responses without it.

Source

Thrown at packages/core/src/services/variable-extraction/service.ts:227

      // 验证必需字段
      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.`);
      }

      return {
        name: variable.name.trim(),
        value: variable.value,
        position: {

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Log the raw response and confirm the position object's actual keys
  2. Update the extraction prompt to require originalText exactly (include a one-shot example in the template)
  3. Recover programmatically: if position.occurrence exists but originalText is missing, populate it from variable.value before parsing
  4. Retry with a more capable model if the schema is persistently ignored

Example fix

// before
await service.parseExtractionResult(text);

// after
// repair missing originalText from the variable value before parsing
const parsed = JSON.parse(text);
for (const v of parsed.variables ?? []) {
  if (v.position && typeof v.position.originalText !== 'string' && typeof v.value === 'string') {
    v.position.originalText = v.value;
  }
}
await service.parseExtractionResult(JSON.stringify(parsed));
Defensive patterns

Strategy: validation

Validate before calling

for (const v of parsed.variables ?? []) { if (typeof v.position?.originalText !== 'string') v.position.originalText = v.value ?? ''; }

Type guard

const hasOriginalText = (v: any) => typeof v?.position?.originalText === 'string';

Try / catch

catch (e) { if (e instanceof VariableExtractionParseError && e.message.includes('originalText')) return repairAndRetry(text); throw e; }

Prevention

When it happens

Trigger: parseExtractionResult receives variables[i].position = { occurrence: 1 } with no originalText, or originalText is a number/boolean instead of a string.

Common situations: LLM emits position: { occurrence: 2 } only; field renamed by the model (e.g. 'text' or 'original'); template version mismatch after upgrade; model outputs null for originalText.

Related errors


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/eb92983324838aa9. Report an issue: GitHub.