koala73/worldmonitor · error
EONET malformed event geometry
Error message
EONET malformed event geometry
What it means
Thrown by fetchEonet when an event's latest geometry entry is missing, is not a Point/Polygon, or lacks a coordinates array. The seeder validates each event's most recent geometry before extracting lon/lat for Point records.
Solutions
- Inspect the raw EONET response to identify events with empty/odd geometry; confirm whether the API is returning partial data.
- Retry the seed to rule out a transient truncated response.
- Change the handling to skip (continue) events with unusable geometry rather than throwing for the whole batch.
- If persistent, check EONET API changelog for geometry format changes and update the validator.
Example fix
// before
if (!latestGeo || !['Point', 'Polygon'].includes(latestGeo.type) || !Array.isArray(latestGeo.coordinates)) {
throw new Error('EONET malformed event geometry');
}
// after
if (!latestGeo || !['Point', 'Polygon'].includes(latestGeo.type) || !Array.isArray(latestGeo.coordinates)) {
console.warn('Skipping EONET event with malformed geometry', event.id);
continue;
} Defensive patterns
Strategy: validation
Validate before calling
const geoOk = (data?.events || []).every(e => { const g = e?.geometry?.[e.geometry.length - 1]; return g && ['Point','Polygon'].includes(g.type) && Array.isArray(g.coordinates); }); Type guard
function hasValidGeometry(event) { const g = event?.geometry?.[event.geometry.length - 1]; return !!g && ['Point', 'Polygon'].includes(g.type) && Array.isArray(g.coordinates); } Try / catch
try { const events = await fetchEonet(fetchFn); } catch (e) { if (e.message === 'EONET malformed event geometry') { console.error('An EONET event lacked usable geometry; check for empty geometry arrays'); } throw e; } Prevention
- Treat empty geometry arrays as skippable events, not fatal errors
- Log event ids of skipped/malformed records for upstream reporting
- Cache the last good EONET snapshot and fall back to it on validation failure
- Test the seeder against a recorded EONET fixture to catch schema drift early
When it happens
Trigger: event.geometry is empty or undefined; the last geometry item has a type outside ['Point','Polygon'] (e.g. missing type), or its coordinates is not an array.
Common situations: EONET serving events with empty geometry arrays (very new or archived events); upstream schema changes to geometry entries; cached/partial API responses in CI.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- EONET malformed event category
- GDACS malformed response
- ECCC_MALFORMED_PAGE
- EONET malformed event
- : editorialLinks must be an array
AI-assisted analysis of koala73/worldmonitor@e586b8b4b8 (2026-09-22).
Data as JSON: /api/errors/ea3d506031278fd7.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/seed-natural-events.mjs:259
}
}, 1, 500);
}
async function fetchEonet(days, fetchFn = globalThis.fetch, now = Date.now()) {
const url = `${EONET_API_URL}?status=open&days=${days}`;
const data = await fetchEventSourceJson('eonet', url, fetchFn);
if (!Array.isArray(data?.events)) throw new Error('EONET malformed response');
const events = [];
for (const event of data.events || []) {
const category = event.categories?.[0];
if (!category) throw new Error('EONET malformed event category');
const normalizedCategory = normalizeCategory(category.id);
if (normalizedCategory === 'earthquakes') continue;
const latestGeo = event.geometry?.[event.geometry.length - 1];
if (!latestGeo || !['Point', 'Polygon'].includes(latestGeo.type) || !Array.isArray(latestGeo.coordinates)) {
throw new Error('EONET malformed event geometry');
}
if (latestGeo.type !== 'Point') continue;
const eventDate = new Date(latestGeo.date);
const [lon, lat] = latestGeo.coordinates;
if (normalizedCategory === 'wildfires' && now - eventDate.getTime() > WILDFIRE_MAX_AGE_MS) continue;
const source = event.sources?.[0];
events.push({
id: event.id || '',
title: event.title || '',
description: event.description || '',
category: normalizedCategory,
categoryTitle: category.title || '',
lat,
lon,
date: eventDate.getTime(),View on GitHub (pinned to e586b8b4b8)