linshenkx/prompt-optimizer · error · VariableExtractionParseError

variables[ ].position is missing a valid "originalText"…

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.

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.

Appendix: 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)