koala73/worldmonitor · error · TypeError

Ok physical divergence reading has an invalid index: ${metal

Error message

Ok physical divergence reading has an invalid index: ${metal}

What it means

After collecting readings, buildPhysicalStressComposite requires every metal's reading to have a finite numeric index (Number.isFinite), because the composite is a weighted sum of indexes. A missing, null, NaN, or non-numeric index on an 'ok'-labeled path throws this TypeError naming the offending metal.

Source

Thrown at shared/physical-divergence-contract.js:175

      };
    }
  }
  for (const state of NON_OK_STATE_PRIORITY) {
    for (const metal of METAL_ORDER) {
      if (byMetal.get(metal).state === state) {
        return {
          state,
          reason: `member_not_ok:${metal}:${state}`,
          index: null,
          weights,
          methodologyVersion: METHODOLOGY_VERSION,
        };
      }
    }
  }
  for (const metal of METAL_ORDER) {
    if (!Number.isFinite(byMetal.get(metal).index)) {
      throw new TypeError(`Ok physical divergence reading has an invalid index: ${metal}`);
    }
  }
  const index = METAL_ORDER.reduce((sum, metal) => (
    sum + byMetal.get(metal).index * PHYSICAL_DIVERGENCE_CONTRACT.metals[metal].weight
  ), 0);
  return {
    state: 'ok',
    reason: '',
    index: Math.round((index + Number.EPSILON) * 100) / 100,
    weights,
    methodologyVersion: METHODOLOGY_VERSION,
  };
}

View on GitHub (pinned to 9361220cc0)

Solutions

  1. Ensure every reading has a finite numeric index before the call
  2. Coerce/validate: Number.isFinite(Number(reading.index)) and reject or default otherwise
  3. Fix upstream computation that yields NaN (check for empty series, divide-by-zero)
  4. Skip or downstate such readings (use a non-'ok' state like 'missing_input') instead of including them

Example fix

// before
buildPhysicalStressComposite([{ metal: 'gold', state: 'ok', index: NaN }])
// after
const idx = Number(rawIndex);
const reading = Number.isFinite(idx)
  ? { metal: 'gold', state: 'ok', index: idx }
  : { metal: 'gold', state: 'missing_input' };
Defensive patterns

Strategy: validation

Validate before calling

function hasFiniteIndexes(readings) {
  return (Array.isArray(readings) ? readings : [])
    .filter((r) => r?.state === 'ok')
    .every((r) => Number.isFinite(r.index));
}

Type guard

function hasFiniteIndex(r) {
  return r != null && Number.isFinite(r.index);
}

Try / catch

try {
  composite = buildPhysicalStressComposite(readings);
} catch (e) {
  if (e instanceof TypeError && e.message.startsWith('Ok physical divergence reading has an invalid index')) {
    const metal = e.message.split(': ')[1];
    // drop or downgrade the offending metal's reading
  } else throw e;
}

Prevention

When it happens

Trigger: Passing { metal:'gold', state:'ok' } with no index, index: NaN (e.g. from parseFloat of an empty string), index as a string ('1.2'), or null from a failed computation.

Common situations: Upstream feed gaps producing NaN; JSON deserialization turning numbers into strings; division producing NaN when a denominator is zero; forgot-to-set index after computing a normalized score.

Related errors


AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01). Data as JSON: /api/errors/92253261bb0a5f33. Report an issue: GitHub.