koala73/worldmonitor · error
Unsupported worksheet format.
Error message
Unsupported worksheet format.
What it means
importOperationalWorksheet only accepts JSON whose top-level schema field equals 'worldmonitor-operational-worksheet/v1'. Any other string (or a missing schema key) throws, so exports from other tools or future/older schema versions fail fast instead of being parsed with wrong assumptions.
Solutions
- Ensure the imported JSON is a full worksheet export containing schema: 'worldmonitor-operational-worksheet/v1' at the top level.
- Re-export the worksheet from the same WorldMonitor version rather than reconstructing JSON by hand.
- If importing legacy data, wrap it: { schema: 'worldmonitor-operational-worksheet/v1', input: legacyInput }.
- Check the schema string for typos/exact casing; it must match character for character.
Example fix
// before
importOperationalWorksheet('{"operation":"Ops","basis":"user",...}');
// after
const input = JSON.parse(raw);
importOperationalWorksheet(JSON.stringify({ schema: 'worldmonitor-operational-worksheet/v1', input })); Defensive patterns
Strategy: try-catch
Validate before calling
const parsed = JSON.parse(text);
if (parsed?.schema !== 'worldmonitor-operational-worksheet/v1') {
throw new Error('Not a worldmonitor-operational-worksheet/v1 export.');
} Type guard
const isWorksheetV1 = (v: unknown): v is { schema: 'worldmonitor-operational-worksheet/v1'; input: unknown } =>
typeof v === 'object' && v !== null && (v as any).schema === 'worldmonitor-operational-worksheet/v1'; Try / catch
try {
const snapshot = importOperationalWorksheet(text);
} catch (err) {
if (err instanceof Error && err.message === 'Unsupported worksheet format.') {
showImportError('This does not look like a WorldMonitor operational worksheet export (expected schema worldmonitor-operational-worksheet/v1).');
} else throw err;
} Prevention
- Only import files produced by this app's own export button; never reconstruct wrapper JSON by hand.
- Check the schema key first thing after JSON.parse and surface a targeted message.
- Handle /v2-style future exports with an explicit 'unsupported version' branch rather than a generic failure.
When it happens
Trigger: Calling importOperationalWorksheet(text) where JSON.parse succeeded but value.schema is absent, or is something other than 'worldmonitor-operational-worksheet/v1' — e.g. a generic JSON object pasted by mistake, an export from a different WorldMonitor worksheet type, or a hand-edited file with the schema key renamed/typo'd.
Common situations: Pasting arbitrary JSON (a config file, API response) into the import box; importing an older export produced before the /v1 schema tag existed; a future version exporting /v2 that this runtime doesn't recognize; copying only the inner input object without the wrapper that carries schema.
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
- batch exceeds ${COMPANY_MONITORING_LIMITS.maxImportRows} row
- batch rows must share one clientImportId
- batch ordinals must be contiguous from 0
- batch exceeds ${COMPANY_MONITORING_LIMITS.maxImportBatchByte
- Physical divergence snapshot must contain gold and silver re
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/8a0516fb5c328d1f.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils/operational-balance.ts:78
const available = round(stock + arrivals);
const unmetDemand = round(Math.max(0, demand - available));
stock = round(Math.max(0, available - demand));
return { day: index + 1, date, arrivals, demand, closingStock: stock, unmetDemand };
});
return { days, firstGapDay: days.find(day => day.unmetDemand > 0)?.day ?? null, totalUnmetDemand: round(days.reduce((sum, day) => sum + day.unmetDemand, 0)) };
};
const baseline = balance(input.deliveries, input.dailyDemand);
const alternative = balance([...input.deliveries, ...input.alternativeDeliveries], input.alternativeDailyDemand ?? input.dailyDemand);
const costsKnown = [...input.deliveries, ...input.alternativeDeliveries].every(row => row.costUsd !== null);
return { schema: 'worldmonitor-operational-worksheet/v1', input, baseline, alternative,
avoidedUnmetDemand: round(baseline.totalUnmetDemand - alternative.totalUnmetDemand),
additionalDeliveryCostUsd: costsKnown ? round(input.alternativeDeliveries.reduce((sum, row) => sum + row.costUsd!, 0)) : null };
}
export function importOperationalWorksheet(text: string): OperationalSnapshot {
if (new TextEncoder().encode(text).length > MAX_OPERATIONAL_JSON_BYTES) throw new Error('Worksheet JSON must be no larger than 64 KiB.');
const value = record(JSON.parse(text));
if (value.schema !== 'worldmonitor-operational-worksheet/v1') throw new Error('Unsupported worksheet format.');
return calculateOperationalBalance(value.input);
}
export function operationalExample(): OperationalInput {
return { operation: 'Example operation', basis: 'example', unit: 'units', startDate: '2026-09-10', horizonDays: 10, startingStock: 100, dailyDemand: 20,
deliveries: [{ date: '2026-09-13', quantity: 40, unit: 'units', costUsd: null }], alternativeDeliveries: [], alternativeDailyDemand: null };
}
View on GitHub (pinned to 7d06c8633d)