koala73/worldmonitor · error · TypeError
Physical divergence composite repeats a metal: ${reading.met
Error message
Physical divergence composite repeats a metal: ${reading.metal} What it means
Assertion error raised by shared/physical-divergence-contract.js when the physical divergence composite calculation receives a readings list containing the same metal more than once. Each metal must appear exactly once so the composite divergence score is unambiguous; duplicates make the per-metal weighting invalid, so the contract fails fast with the offending metal named in the message. Fix upstream by deduplicating readings (e.g., keep the latest reading per metal) before calling the composite builder.
Source
Thrown at shared/physical-divergence-contract.js:137
return STORED_READING_REASONS_BY_STATE[state]?.includes(reason) === true;
}
export function isPhysicalDivergenceStoredCompositeReason(state, reason) {
if (state === 'ok') return reason === '';
return NON_OK_STATE_PRIORITY.includes(state)
&& COMPOSITE_MEMBER_REASONS.includes(reason)
&& reason.endsWith(`:${state}`);
}
export function buildPhysicalStressComposite(readings) {
const values = Array.isArray(readings) ? readings : [];
const byMetal = new Map();
for (const reading of values) {
if (!METAL_ORDER.includes(reading?.metal)) {
throw new TypeError(`Unsupported physical divergence metal: ${String(reading?.metal)}`);
}
if (byMetal.has(reading.metal)) {
throw new TypeError(`Physical divergence composite repeats a metal: ${reading.metal}`);
}
if (!STATES.includes(reading.state)) {
throw new TypeError(`Unknown physical divergence state: ${String(reading.state)}`);
}
byMetal.set(reading.metal, reading);
}
const weights = METAL_ORDER.map((metal) => ({
metal,
weight: PHYSICAL_DIVERGENCE_CONTRACT.metals[metal].weight,
methodologyVersion: METHODOLOGY_VERSION,
}));
for (const metal of METAL_ORDER) {
if (!byMetal.has(metal)) {
return {
state: 'missing_input',
reason: `member_not_ok:${metal}:missing_input`,
index: null,
weights,View on GitHub (pinned to 9361220cc0)
Solutions
- Dedupe readings by metal (last-wins or newest-timestamp) before the call
- Build readings as a Map keyed by metal so duplicates are impossible
- Assert uniqueness before calling: new Set(readings.map(r => r.metal)).size === readings.length
- Fix the producer to emit exactly one reading per contract metal
Example fix
// before buildPhysicalStressComposite([...snapshotReadings, ...liveReadings]) // after const byMetal = new Map([...snapshotReadings, ...liveReadings].map((r) => [r.metal, r])); buildPhysicalStressComposite([...byMetal.values()])
Defensive patterns
Strategy: validation
Validate before calling
function dedupeByMetal(readings) {
const byMetal = new Map();
for (const r of Array.isArray(readings) ? readings : []) {
if (r?.metal) byMetal.set(r.metal, r); // last wins
}
return [...byMetal.values()];
} Type guard
function hasUniqueMetals(readings) {
const metals = (Array.isArray(readings) ? readings : []).map((r) => r?.metal);
return metals.every((m) => typeof m === 'string') && new Set(metals).size === metals.length;
} Try / catch
try {
composite = buildPhysicalStressComposite(readings);
} catch (e) {
if (e instanceof TypeError && e.message.includes('repeats a metal')) {
composite = buildPhysicalStressComposite(dedupeByMetal(readings));
} else throw e;
} Prevention
- Build reading lists as a Map keyed by metal
- Dedupe when merging snapshot + live data
- Prefer newest-timestamp reading when duplicates arise
- Assert uniqueness in tests for any producer of reading arrays
When it happens
Trigger: Passing duplicate readings for 'gold' or 'silver' — e.g. concatenating two snapshot arrays, appending a live update to an already-complete reading list, or a producer emitting both a stored and a corrected reading.
Common situations: Merging historical + realtime data without dedupe; retry logic re-inserting a reading; upstream publishing the same metal under slightly different keys that normalize to the same metal.
Related errors
- Unknown physical divergence freshness reason: ${String(reaso
- Unsupported physical divergence metal: ${String(reading?.met
- Unknown physical divergence state: ${String(reading.state)}
- Ok physical divergence reading has an invalid index: ${metal
- get-china-decision-signals returned no canonical payload
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/e5eaaa2d201620d3.
Report an issue: GitHub.