koala73/worldmonitor · error · RpcValidationError
Could not resolve to a country.
Error message
Could not resolve ${JSON.stringify(echoCountryInput(raw))} to a country. ${COUNTRY_ARG_HINT} What it means
requireCountryCode() resolves a caller-supplied country argument (name, code, alias) via resolveCountryCode(); if resolution fails it throws RpcValidationError with a field-level description including the echoed (safe, JSON-stringified) input and COUNTRY_ARG_HINT. It fails loudly so an agent can self-correct its arguments.
Solutions
- Pass a valid ISO 3166-1 alpha-2 code (e.g. "CH", "US") — the most reliable form.
- Use the exact country name or alias supported by resolveCountryCode; consult COUNTRY_ARG_HINT in the error message for accepted formats.
- Trim whitespace and fix casing (resolution is typically case-insensitive but exact spelling matters).
- If the entity genuinely has no country code (e.g. an EU-wide query), use the tool's non-country variant or preset parameter instead.
Example fix
// before
callTool('get-country-brief', { country_code: 'Swiss' })
// after
callTool('get-country-brief', { country_code: 'CH' }) Defensive patterns
Strategy: validation
Validate before calling
const resolved = resolveCountryCode(raw);
if (!resolved) {
throw new Error(`"${raw}" is not a recognized country; pass an ISO 3166-1 alpha-2 code like "CH"`);
} Type guard
function isAlpha2(v: unknown): v is string {
return typeof v === 'string' && /^[A-Za-z]{2}$/.test(v);
} Try / catch
try {
const cc = requireCountryCode(raw, 'get-country-brief');
} catch (err) {
if (err instanceof RpcValidationError) {
// inspect err.fields / description; retry once with a normalized alpha-2 code
} else throw err;
} Prevention
- Always pass uppercase ISO 3166-1 alpha-2 codes to MCP country tools.
- Normalize user/agent input through resolveCountryCode before dispatching RPCs.
- Read COUNTRY_ARG_HINT in the error for accepted formats.
- Trim and uppercase strings at the input boundary.
When it happens
Trigger: Calling any MCP RPC tool whose handler calls requireCountryCode (directly or via countryCode()/code()) with a raw value that resolveCountryCode cannot map — misspelled country names, lowercase or non-alpha-2 codes, unknown aliases, non-string types like numbers or objects.
Common situations: An LLM agent passing 'Swiss' or 'CHN'-style typo codes; passing a numeric ISO 3166-1 numeric code; passing localized country names; passing null/undefined when the parameter was optional upstream.
Related errors
- country must be an ISO 3166-1 alpha-2 country code, e.g…
- must be an ISO 3166-1 alpha-2 country code.
- provide exactly one of country_code, preset, or members.
- Could not resolve to a country. Pass an ISO 3166-1 alpha-2…
- countryCode must be a 2-letter ISO 3166-1 alpha-2 code
AI-assisted analysis of koala73/worldmonitor@e586b8b4b8 (2026-09-01).
Data as JSON: /api/errors/4f948e179af6455a.
Report an issue: GitHub.
Appendix: source
Thrown at api/mcp/registry/rpc-tools.ts:90
staleAgeSeconds?: number;
staleReason?: string;
attemptedAt?: string;
};
// Corroboration for the country brief cannot ride on `sources`: that array is
// the proto BriefSource shape (title/source/url/publishedAt) returned by the
// gateway, so widening it would be a proto change, and on the common path the
// server-side sources win anyway. A sibling field keeps the citation list
// exactly as it is. (#4925 item 3)
type McpBriefGroundingStory = {
title: string;
source: string;
url?: string;
publishedAt?: string;
corroborationCount: number;
mentionCount?: number;
storyPhase?: string;
};
// Keep the optional grounding copy smaller than the primary citation list.
// An oversized URL is omitted rather than truncated because a clipped URL is
// no longer a valid citation target. The primary `sources` field remains the
// canonical citation surface.
const MAX_COUNTRY_BRIEF_GROUNDING_URL_LENGTH = 2_000;
function clipBriefText(value: unknown, maxLen: number): string {
if (typeof value !== 'string') return '';
const text = value.replace(/\s+/g, ' ').trim();
return text.length > maxLen ? `${text.slice(0, maxLen - 1).trim()}...` : text;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return !!value && typeof value === 'object' && !Array.isArray(value);
}
/**View on GitHub (pinned to e586b8b4b8)