{"record":{"id":"24fccf2a269008b5","repo":"koala73/worldmonitor","slug":"scenarioid-is-required","errorCode":null,"errorMessage":"scenarioId is required","messagePattern":"scenarioId is required","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"server/worldmonitor/scenario/v1/run-scenario.ts","lineNumber":36,"sourceCode":"\nfunction generateJobId(): string {\n  const ts = Date.now();\n  let suffix = '';\n  const array = new Uint8Array(8);\n  crypto.getRandomValues(array);\n  for (const byte of array) suffix += JOB_ID_CHARSET[byte % JOB_ID_CHARSET.length];\n  return `scenario:${ts}:${suffix}`;\n}\n\nexport async function runScenario(\n  ctx: ServerContext,\n  req: RunScenarioRequest,\n): Promise<RunScenarioResponse> {\n  await requirePremiumRpcAccess(ctx.request, ApiError, 'PRO subscription required');\n\n  const scenarioId = (req.scenarioId ?? '').trim();\n  if (!scenarioId) {\n    throw new ValidationError([{ field: 'scenarioId', description: 'scenarioId is required' }]);\n  }\n  const template = getScenarioTemplate(scenarioId);\n  if (!template) {\n    throw new ValidationError([{ field: 'scenarioId', description: `Unknown scenario: ${scenarioId}` }]);\n  }\n\n  const disruptionPct = req.disruptionPct;\n  if (disruptionPct !== undefined && (\n    !Number.isInteger(disruptionPct) || disruptionPct < 0 || disruptionPct > 100\n    || template.affectedChokepointIds.length === 0\n  )) {\n    throw new ValidationError([{ field: 'disruptionPct', description: 'disruptionPct must be an integer from 0 to 100 for a physical scenario' }]);\n  }\n\n  const iso2 = req.iso2 ? req.iso2.trim() : '';\n  if (iso2 && !/^[A-Z]{2}$/.test(iso2)) {\n    throw new ValidationError([{ field: 'iso2', description: 'iso2 must be a 2-letter uppercase country code' }]);\n  }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/server/worldmonitor/scenario/v1/run-scenario.ts#L18-L54","documentation":"Request validation in runScenario: req.scenarioId is empty after trim. The premium access check has already passed; the validation fails because no scenario template was named, so there is nothing to enqueue for the worker.","triggerScenarios":"Thrown at server/worldmonitor/scenario/v1/run-scenario.ts:36 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass a non-empty scenarioId from the scenario catalog","Default the UI to a selected scenario so the field cannot be submitted blank"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}