koala73/worldmonitor · error · TypeError
Physical divergence evaluation clock is invalid
Error message
Physical divergence evaluation clock is invalid
What it means
applyFreshness() stamps each reading with staleness computed against a wall-clock timestamp nowMs. If nowMs is not a finite number (NaN, Infinity, undefined coerced oddly, a string) it throws this TypeError immediately, because staleness decisions against an invalid clock would be meaningless.
Source
Thrown at server/_shared/physical-divergence-snapshot.ts:381
methodology(raw.methodologyVersion);
canonicalWeights(raw.weights);
const expected = buildPhysicalStressComposite(readings);
const actualState = state(raw.state);
const actualIndex = nullableFinite(raw.index);
if (
!string(raw.reason)
|| !isPhysicalDivergenceStoredCompositeReason(actualState, raw.reason)
|| actualState !== expected.state
|| raw.reason !== expected.reason
|| actualIndex !== expected.index
) throw new TypeError('Physical divergence composite does not match its member readings');
}
function applyFreshness(
readings: PhysicalDivergenceRawReading[],
nowMs: number,
): PhysicalDivergenceRawReading[] {
if (!Number.isFinite(nowMs)) throw new TypeError('Physical divergence evaluation clock is invalid');
return readings.map((entry) => {
if (entry.state !== 'ok' && entry.state !== 'insufficient_history') return entry;
const staleReason = physicalDivergenceStaleReason({
physicalAsOf: entry.physicalAsOf,
paperAsOf: entry.paperAsOf,
fxAsOf: entry.provenance.fxAsOf,
}, nowMs);
if (!staleReason) return entry;
return {
...entry,
state: physicalDivergenceStateForFreshnessReason(staleReason),
reason: staleReason,
regime: null,
index: null,
percentile: null,
robustZ: null,
delta5d: null,
delta20d: null,View on GitHub (pinned to 9361220cc0)
Solutions
- Pass a finite epoch-milliseconds number: Number.isFinite(nowMs) must hold — use Date.now() by default.
- If the clock comes from config/tests, coerce and validate it first: const t = Number(raw); if (!Number.isFinite(t)) throw ...
- Fix test fakes to return a finite number from the clock function.
- If a timestamp string is the source, parse it with Date.parse(...) and check for NaN before passing.
Example fix
// before applyFreshness(readings, config.evaluationClock); // string // after const nowMs = Number(config.evaluationClock); if (!Number.isFinite(nowMs)) nowMs = Date.now(); applyFreshness(readings, nowMs);
Defensive patterns
Strategy: validation
Validate before calling
const nowMs = clock?.() ?? Date.now();
if (!Number.isFinite(nowMs)) throw new Error(`evaluation clock must be finite epoch ms, got ${nowMs}`); Type guard
function isFiniteEpochMs(v: unknown): v is number {
return typeof v === 'number' && Number.isFinite(v) && v > 0;
} Try / catch
try {
applyFreshness(readings, nowMs);
} catch (err) {
if (err instanceof TypeError && err.message.includes('evaluation clock is invalid')) {
applyFreshness(readings, Date.now()); // fall back to wall clock
} else throw err;
} Prevention
- Validate injected test clocks return finite numbers.
- Convert timestamp strings with Date.parse and check for NaN before use.
- Default to Date.now() when no clock is supplied.
- Never do arithmetic on possibly-missing timestamp fields without a Number.isFinite check.
When it happens
Trigger: Calling applyFreshness (via the snapshot normalization pipeline: readings -> normalizePhysicalDivergenceSnapshot -> getPhysicalDivergenceIndex) with nowMs that is NaN, Infinity, undefined-as-NaN, or a non-numeric type — e.g. Date.now() replaced by an unparseable injected clock in tests or a corrupted config value.
Common situations: Tests injecting a fake clock that returns undefined; configuration supplying a timestamp string ('2026-09-01T...') instead of epoch ms; arithmetic on a missing field producing NaN; Date.now() monkey-patched incorrectly.
Related errors
- Physical divergence composite repeats a metal weight
- Physical divergence snapshot has an invalid envelope
- Physical divergence composite does not match its member read
- get_intel_timeline requires at least one of domain ("conflic
- failed to build coverage snapshot
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/a1d47a1487553ee6.
Report an issue: GitHub.