koala73/worldmonitor · error
${relativePath} is missing required live-pulse sections
Error message
${relativePath} is missing required live-pulse sections What it means
resolveLatestLivePulseSnapshotPath validates the frozen live-pulse snapshot JSON. Besides matching the filename date to capturedAt, the snapshot must contain all required sections: countries, chokepoints, crises, and signalConvergence. If any is missing/falsy, it throws '<relativePath> is missing required live-pulse sections' so downstream pages can't render from a partial snapshot.
Solutions
- Run `npm run freeze:crawlable-live-pulse` to regenerate a complete snapshot with all four sections.
- If the snapshot was hand-edited, restore the missing section or regenerate rather than patching.
- Check the freeze script/template writes the exact key names: countries, chokepoints, crises, signalConvergence.
- Delete stale pre-schema snapshots and re-freeze so the latest file conforms.
Example fix
// before (snapshot JSON)
{ "capturedAt": "2026-09-15", "countries": [...], "crises": [...] }
// after
{ "capturedAt": "2026-09-15", "countries": [...], "chokepoints": [...], "crises": [...], "signalConvergence": [...] } Defensive patterns
Strategy: validation
Validate before calling
const snap = JSON.parse(fs.readFileSync(snapshotPath, 'utf8'));
for (const key of ['countries', 'chokepoints', 'crises', 'signalConvergence']) {
if (!snap[key]) throw new Error(`${snapshotPath} missing ${key}`);
} Type guard
const isCompleteSnapshot = (s) => Boolean(s?.countries && s?.chokepoints && s?.crises && s?.signalConvergence);
Prevention
- Never hand-edit frozen snapshot JSON; always regenerate via the freeze script.
- Version the snapshot schema and migrate old files instead of leaving partial ones.
When it happens
Trigger: Loading a snapshot file from the crawlable live-pulse directory whose parsed JSON lacks any of countries, chokepoints, crises, or signalConvergence keys (each must be truthy).
Common situations: A manually edited or truncated snapshot JSON; a new freeze script version writing a renamed section (e.g. chokepoint vs chokepoints); an old snapshot committed before signalConvergence existed; a failed freeze left a partial file.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ${relativePath} is ${Math.round(ageDays)} days old (max ${MA
- ${pagePath} claims "${claim}" against a ${Math.round(ageDays
- ${PRO_HTML_PATH} must carry exactly one dateModified node (f
- Exa search failed HTTP ${resp.status}: ${text.slice(0, 120)}
- failed to build coverage snapshot
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/bad00dbd1f834a7c.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/build-crawlable-corpus.mjs:477
const snapshotDir = repoPath(rootDir, RESILIENCE_SNAPSHOT_DIR);
const candidates = readdirSync(snapshotDir)
.map((filename) => ({ filename, match: filename.match(LIVE_PULSE_SNAPSHOT_RE) }))
.filter(({ match }) => match)
.sort((a, b) => b.match[1].localeCompare(a.match[1]));
if (candidates.length === 0) {
throw new Error(`No crawlable live-pulse snapshot found in ${RESILIENCE_SNAPSHOT_DIR}`);
}
const [{ filename, match }] = candidates;
const relativePath = join(RESILIENCE_SNAPSHOT_DIR, filename);
const snapshot = readJson(rootDir, relativePath);
if (snapshot.capturedAt !== match[1]) {
throw new Error(
`${relativePath} filename date ${match[1]} does not match capturedAt ${snapshot.capturedAt}`,
);
}
if (!snapshot.countries || !snapshot.chokepoints || !snapshot.crises || !snapshot.signalConvergence) {
throw new Error(`${relativePath} is missing required live-pulse sections`);
}
const ageDays = livePulseSnapshotAgeDays(snapshot.capturedAt);
if (ageDays > MAX_LIVE_PULSE_SNAPSHOT_AGE_DAYS) {
throw new Error(
`${relativePath} is ${Math.round(ageDays)} days old (max ${MAX_LIVE_PULSE_SNAPSHOT_AGE_DAYS}); `
+ 'run `npm run freeze:crawlable-live-pulse` to republish current values',
);
}
return relativePath;
}
function formatStaticDateTime(iso) {
const timestamp = Date.parse(iso);
if (!Number.isFinite(timestamp)) return String(iso || '');
return new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',View on GitHub (pinned to 7d06c8633d)