{"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  if (!getScenarioTemplate(scenarioId)) {\n    throw new ValidationError([{ field: 'scenarioId', description: `Unknown scenario: ${scenarioId}` }]);\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  }\n\n  // Queue-depth backpressure. Raw key: worker reads it unprefixed, so we must too.\n  const [depthEntry] = await runRedisPipeline([['LLEN', QUEUE_KEY]], true);\n  const depth = typeof depthEntry?.result === 'number' ? depthEntry.result : 0;\n  if (depth > MAX_QUEUE_DEPTH) {\n    throw new ApiError(429, 'Scenario queue is at capacity, please try again later', '');\n  }\n\n  const jobId = generateJobId();","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/koala73/worldmonitor/blob/eeab0a219fce0f02a00603b532dbae9041b934ac/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":"eeab0a219fce0f02a00603b532dbae9041b934ac","analyzedAt":"2026-08-21T16:51:25.751Z","contentChangedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}