{"record":{"id":"ee3c6bf679d24c70","repo":"koala73/worldmonitor","slug":"iso2-must-be-a-2-letter-uppercase-country-code","errorCode":null,"errorMessage":"iso2 must be a 2-letter uppercase country code","messagePattern":"iso2 must be a 2-letter uppercase country code","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"server/worldmonitor/scenario/v1/run-scenario.ts","lineNumber":44,"sourceCode":"}\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();\n  const payload = JSON.stringify({\n    jobId,\n    scenarioId,\n    iso2: iso2 || null,\n    enqueuedAt: Date.now(),\n  });\n\n  // Upstash RPUSH returns the new list length; helper returns [] on transport","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/koala73/worldmonitor/blob/eeab0a219fce0f02a00603b532dbae9041b934ac/server/worldmonitor/scenario/v1/run-scenario.ts#L26-L62","documentation":"Validation error in runScenario: the optional iso2 parameter was provided but does not match the 2-letter uppercase ISO 3166-1 alpha-2 pattern after trimming. It is a caller-input validation guard, not a server failure; the scenario cannot be scoped to an invalid country.","triggerScenarios":"Thrown at server/worldmonitor/scenario/v1/run-scenario.ts:44 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Send iso2 as exactly two uppercase letters (e.g. 'US', 'GB')","Omit iso2 entirely to run the scenario without a country scope","Trim whitespace before sending; lowercase codes like 'us' are rejected"],"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-14T00:17:10.932Z"}