{"record":{"id":"e2609412346b2244","repo":"koala73/worldmonitor","slug":"must-be-an-iso-3166-1-alpha-2-country-code","errorCode":null,"errorMessage":"must be an ISO 3166-1 alpha-2 country code.","messagePattern":"must be an ISO 3166-1 alpha-2 country code\\.","errorType":"validation","errorClass":"RpcValidationError","httpStatus":400,"severity":"error","filePath":"api/mcp/registry/rpc-tools.ts","lineNumber":2207,"sourceCode":"          description: 'Custom bloc of 2-30 unique uppercase ISO-2 member codes. Mutually exclusive with country_code and preset.',\n        },\n      },\n      required: [],\n      oneOf: [\n        { required: ['country_code'] },\n        { required: ['preset'] },\n        { required: ['members'] },\n      ],\n    },\n    outputSchema: FIVE_FACTOR_SCORECARD_OUTPUT_SCHEMA,\n    annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },\n    _coverageKeys: ['scorecard:five-factor:v1', 'seed-meta:scorecard:five-factor'],\n    _execute: async (params, base, context, execution) => {\n      const countryCode = argStr(params.country_code).trim().toUpperCase();\n      const preset = argStr(params.preset).trim().toUpperCase();\n      const members = Array.isArray(params.members) ? params.members : [];\n      const selectors = Number(countryCode.length > 0) + Number(preset.length > 0) + Number(members.length > 0);\n      if (selectors !== 1) {\n        throw new RpcValidationError('get-five-factor-scorecard', [{\n          field: 'selection',\n          description: 'provide exactly one of country_code, preset, or members.',\n        }]);\n      }\n\n      const q = new URLSearchParams();\n      let path: string;\n      if (countryCode) {\n        if (!/^[A-Z]{2}$/.test(countryCode)) {\n          throw new RpcValidationError('get-five-factor-scorecard', [{\n            field: 'country_code',\n            description: 'must be an ISO 3166-1 alpha-2 country code.',\n          }]);\n        }\n        path = '/api/scorecard/v1/get-five-factor-scorecard';\n        q.set('countryCode', countryCode);\n      } else {","sourceCodeStart":2189,"sourceCodeEnd":2225,"githubUrl":"https://github.com/koala73/worldmonitor/blob/e586b8b4b80f595aa7ece295eec10d76f2921240/api/mcp/registry/rpc-tools.ts#L2189-L2225","documentation":"After selecting the country_code variant, get-five-factor-scorecard validates the value against /^[A-Z]{2}$/ (ISO 3166-1 alpha-2). Anything else — lowercase codes, 3-letter alpha-3 codes, full names — throws RpcValidationError on field country_code. The internal scorecard API expects the strict two-letter uppercase form.","triggerScenarios":"Calling get-five-factor-scorecard with country_code values like 'deu', 'DEU', 'Germany', 'D', or '' that survived the selector check but fail the alpha-2 regex.","commonSituations":"Agents emitting alpha-3 codes (ISO 3166-1 alpha-3) or FIPS codes; frontend inputs not normalized to uppercase; passing a human-readable country name because the selector check allowed it through as the single selector.","solutions":["Normalize the input to a two-letter uppercase ISO 3166-1 alpha-2 code before calling ('DEU' -> 'DE', 'germany' -> 'DE').","Reuse the registry's resolveCountryCode helper (as requireCountryCode does) to convert names/aliases to alpha-2 client-side.","Validate with /^[A-Z]{2}$/ in the caller before dispatching the RPC.","For scorecard queries on non-ISO entities, switch to the preset or members selector instead."],"exampleFix":"// before\ncallTool('get-five-factor-scorecard', { country_code: 'DEU' })\n// after\nconst cc = resolveCountryCode('DEU'); // 'DE'\ncallTool('get-five-factor-scorecard', { country_code: cc })","handlingStrategy":"validation","validationCode":"function isAlpha2Country(v: unknown): v is string {\n  return typeof v === 'string' && /^[A-Z]{2}$/.test(v);\n}\nif (!isAlpha2Country(params.country_code)) throw new Error('country_code must be ISO 3166-1 alpha-2, e.g. \"DE\"');","typeGuard":"function isIsoAlpha2(v: unknown): v is string {\n  return typeof v === 'string' && /^[A-Z]{2}$/.test(v);\n}","tryCatchPattern":"try {\n  return await callTool('get-five-factor-scorecard', { country_code: cc });\n} catch (err) {\n  if (err instanceof RpcValidationError && err.fields?.[0]?.field === 'country_code') {\n    const fixed = resolveCountryCode(cc);\n    if (fixed) return await callTool('get-five-factor-scorecard', { country_code: fixed });\n  }\n  throw err;\n}","preventionTips":["Normalize alpha-3 codes and names to alpha-2 via resolveCountryCode before calling.","Uppercase country inputs at the boundary (the regex requires A-Z).","Validate with /^[A-Z]{2}$/ in any client that constructs scorecard requests.","Prefer shared country-resolution helpers over ad-hoc string handling."],"tags":["validation","mcp","rpc","iso-3166","country-code"],"backgroundTag":"rpc-validation-error","analyzedSha":"e586b8b4b80f595aa7ece295eec10d76f2921240","analyzedAt":"2026-09-01T10:32:37.851Z","contentChangedAt":"2026-09-01T10:32:37.851Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}