linshenkx/prompt-optimizer · error · VariableExtractionParseError

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

Error message

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

What it means

normalizeExtractionResponse requires each variable's position to include a numeric occurrence field indicating which occurrence of originalText the variable points at. This error means occurrence is missing or not a number (string counts like "2" are rejected).

Source

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

        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: {
          originalText: variable.position.originalText,
          occurrence: variable.position.occurrence,
        },
        reason: variable.reason,
        category: variable.category ? String(variable.category) : undefined,
      };

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Coerce string occurrences to numbers before parsing if you control the payload
  2. Fix the prompt/template to state occurrence must be a JSON number, not a string
  3. Check whether the model renamed the field and remap it (e.g. position.index -> position.occurrence)
  4. Log the raw response to confirm the exact offending shape

Example fix

// before
await service.parseExtractionResult(text);

// after
const parsed = JSON.parse(text);
for (const v of parsed.variables ?? []) {
  const occ = v.position?.occurrence ?? v.position?.index;
  if (typeof occ === 'string' && /^\d+$/.test(occ)) v.position.occurrence = Number(occ);
  else if (typeof v.position?.index === 'number') v.position.occurrence = v.position.index;
}
await service.parseExtractionResult(JSON.stringify(parsed));
Defensive patterns

Strategy: validation

Validate before calling

for (const v of parsed.variables ?? []) { const occ = v.position?.occurrence ?? v.position?.index; if (typeof occ === 'string' && /^\d+$/.test(occ)) v.position.occurrence = Number(occ); else if (typeof occ !== 'number') v.position.occurrence = 0; }

Type guard

const hasOccurrence = (v: any) => typeof v?.position?.occurrence === 'number';

Try / catch

catch (e) { if (e instanceof VariableExtractionParseError && e.message.includes('occurrence')) { /* coerce and retry parse */ } throw e; }

Prevention

When it happens

Trigger: variables[i].position = { originalText: "foo" } with no occurrence, or occurrence: "1" / null / true instead of a number.

Common situations: LLMs frequently return occurrence as a quoted string; schema drift where the field is renamed to 'index' or 'nth'; models omitting the field when there is only one occurrence.

Related errors


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