koala73/worldmonitor · error · RpcValidationError
must be an ISO 3166-1 alpha-2 country code.
Error message
must be an ISO 3166-1 alpha-2 country code.
What it means
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.
Source
Thrown at api/mcp/registry/rpc-tools.ts:2163
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
_coverageKeys: ['scorecard:five-factor:v1', 'seed-meta:scorecard:five-factor'],
_execute: async (params, base, context) => {
const countryCode = argStr(params.country_code).trim().toUpperCase();
const preset = argStr(params.preset).trim().toUpperCase();
const members = Array.isArray(params.members) ? params.members : [];
const selectors = Number(countryCode.length > 0) + Number(preset.length > 0) + Number(members.length > 0);
if (selectors !== 1) {
throw new RpcValidationError('get-five-factor-scorecard', [{
field: 'selection',
description: 'provide exactly one of country_code, preset, or members.',
}]);
}
const q = new URLSearchParams();
let path: string;
if (countryCode) {
if (!/^[A-Z]{2}$/.test(countryCode)) {
throw new RpcValidationError('get-five-factor-scorecard', [{
field: 'country_code',
description: 'must be an ISO 3166-1 alpha-2 country code.',
}]);
}
path = '/api/scorecard/v1/get-five-factor-scorecard';
q.set('countryCode', countryCode);
} else {
path = '/api/scorecard/v1/get-bloc-scorecard';
if (preset) q.set('preset', preset);
else members.forEach((member) => q.append('members', String(member)));
}
const url = `${base}${path}?${q.toString()}`;
const auth = await buildAuthHeaders(context, 'GET', url, null);
const res = await fetch(url, {
headers: { ...auth, 'User-Agent': 'worldmonitor-mcp-edge/1.0' },
signal: AbortSignal.timeout(8_000),
});View on GitHub (pinned to 9361220cc0)
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.
Example fix
// before
callTool('get-five-factor-scorecard', { country_code: 'DEU' })
// after
const cc = resolveCountryCode('DEU'); // 'DE'
callTool('get-five-factor-scorecard', { country_code: cc }) Defensive patterns
Strategy: validation
Validate before calling
function isAlpha2Country(v: unknown): v is string {
return typeof v === 'string' && /^[A-Z]{2}$/.test(v);
}
if (!isAlpha2Country(params.country_code)) throw new Error('country_code must be ISO 3166-1 alpha-2, e.g. "DE"'); Type guard
function isIsoAlpha2(v: unknown): v is string {
return typeof v === 'string' && /^[A-Z]{2}$/.test(v);
} Try / catch
try {
return await callTool('get-five-factor-scorecard', { country_code: cc });
} catch (err) {
if (err instanceof RpcValidationError && err.fields?.[0]?.field === 'country_code') {
const fixed = resolveCountryCode(cc);
if (fixed) return await callTool('get-five-factor-scorecard', { country_code: fixed });
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- country must be an ISO 3166-1 alpha-2 country code, e.g. "UA
- Could not resolve ${JSON.stringify(echoCountryInput(raw))} t
- get_intel_timeline requires at least one of domain ("conflic
- fromIso2 and toIso2 must be valid 2-letter ISO country codes
- iso2 must be a 2-letter uppercase ISO country code
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/e2609412346b2244.
Report an issue: GitHub.