{"record":{"id":"8a0516fb5c328d1f","repo":"koala73/worldmonitor","slug":"unsupported-worksheet-format","errorCode":null,"errorMessage":"Unsupported worksheet format.","messagePattern":"Unsupported worksheet format\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/utils/operational-balance.ts","lineNumber":78,"sourceCode":"      const available = round(stock + arrivals);\n      const unmetDemand = round(Math.max(0, demand - available));\n      stock = round(Math.max(0, available - demand));\n      return { day: index + 1, date, arrivals, demand, closingStock: stock, unmetDemand };\n    });\n    return { days, firstGapDay: days.find(day => day.unmetDemand > 0)?.day ?? null, totalUnmetDemand: round(days.reduce((sum, day) => sum + day.unmetDemand, 0)) };\n  };\n  const baseline = balance(input.deliveries, input.dailyDemand);\n  const alternative = balance([...input.deliveries, ...input.alternativeDeliveries], input.alternativeDailyDemand ?? input.dailyDemand);\n  const costsKnown = [...input.deliveries, ...input.alternativeDeliveries].every(row => row.costUsd !== null);\n  return { schema: 'worldmonitor-operational-worksheet/v1', input, baseline, alternative,\n    avoidedUnmetDemand: round(baseline.totalUnmetDemand - alternative.totalUnmetDemand),\n    additionalDeliveryCostUsd: costsKnown ? round(input.alternativeDeliveries.reduce((sum, row) => sum + row.costUsd!, 0)) : null };\n}\n\nexport function importOperationalWorksheet(text: string): OperationalSnapshot {\n  if (new TextEncoder().encode(text).length > MAX_OPERATIONAL_JSON_BYTES) throw new Error('Worksheet JSON must be no larger than 64 KiB.');\n  const value = record(JSON.parse(text));\n  if (value.schema !== 'worldmonitor-operational-worksheet/v1') throw new Error('Unsupported worksheet format.');\n  return calculateOperationalBalance(value.input);\n}\n\nexport function operationalExample(): OperationalInput {\n  return { operation: 'Example operation', basis: 'example', unit: 'units', startDate: '2026-09-10', horizonDays: 10, startingStock: 100, dailyDemand: 20,\n    deliveries: [{ date: '2026-09-13', quantity: 40, unit: 'units', costUsd: null }], alternativeDeliveries: [], alternativeDailyDemand: null };\n}\n","sourceCodeStart":60,"sourceCodeEnd":86,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/src/utils/operational-balance.ts#L60-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nimportOperationalWorksheet('{\"operation\":\"Ops\",\"basis\":\"user\",...}');\n// after\nconst input = JSON.parse(raw);\nimportOperationalWorksheet(JSON.stringify({ schema: 'worldmonitor-operational-worksheet/v1', input }));","handlingStrategy":"try-catch","validationCode":"const parsed = JSON.parse(text);\nif (parsed?.schema !== 'worldmonitor-operational-worksheet/v1') {\n  throw new Error('Not a worldmonitor-operational-worksheet/v1 export.');\n}","typeGuard":"const isWorksheetV1 = (v: unknown): v is { schema: 'worldmonitor-operational-worksheet/v1'; input: unknown } =>\n  typeof v === 'object' && v !== null && (v as any).schema === 'worldmonitor-operational-worksheet/v1';","tryCatchPattern":"try {\n  const snapshot = importOperationalWorksheet(text);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Unsupported worksheet format.') {\n    showImportError('This does not look like a WorldMonitor operational worksheet export (expected schema worldmonitor-operational-worksheet/v1).');\n  } else throw err;\n}","preventionTips":["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."],"tags":["validation","schema","import"],"backgroundTag":"schema-validation-failed","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-15T18:17:12.389Z"}