koala73/worldmonitor · error · Error
A valid country code is required for a resilience score gene
Error message
A valid country code is required for a resilience score generation
What it means
Thrown by ensureResilienceScoreGenerationCached in server/worldmonitor/resilience/v1/_shared.ts when the country-code argument cannot be normalized into a 2-letter ISO 3166-1 alpha-2 code. normalizeCountryCode() trims, uppercases, and requires /^[A-Z]{2}$/; anything else (empty, null-ish, 'usa', 'us ', 'U1') yields '' and triggers this error. The generation path is strict because the cache key and trace sidecar are keyed off the normalized code.
Source
Thrown at server/worldmonitor/resilience/v1/_shared.ts:1290
imputationShare: 0,
dataVersion: '',
pillars: [],
schemaVersion: '1.0',
// Plan §U3: missing-cache fallback → not headline-eligible. A
// country without a successful score build can't make the
// PR 6 coverage gate either, so the conservative default is
// false even during the PR-2 "true-by-default" window.
headlineEligible: false,
};
}
export async function ensureResilienceScoreGenerationCached(
countryCode: string,
reader?: ResilienceSeedReader,
): Promise<{ score: GetResilienceScoreResponse; trace: ResilienceScoreTraceSidecar }> {
const normalizedCountryCode = normalizeCountryCode(countryCode);
if (!normalizedCountryCode) {
throw new Error('A valid country code is required for a resilience score generation');
}
await ensureResilienceScoreCached(normalizedCountryCode, reader);
const cached = await getCachedJson(scoreCacheKey(normalizedCountryCode)) as CachedScorePayload | null;
if (cached?._traceGenerationId && cached._traceCacheIdentity) {
const trace = await getCachedJson(
scoreTraceCacheKey(normalizedCountryCode, cached._traceGenerationId),
);
if (isMatchingTraceSidecar(trace, normalizedCountryCode, cached)) {
return {
score: await toPublicCachedScore(normalizedCountryCode, cached),
trace,
};
}
}
// Missing, evicted, or malformed trace references invalidate the complete
// generation. Rebuild score and trace together; never attach a fresh trace toView on GitHub (pinned to 9361220cc0)
Solutions
- Validate and normalize the input first: trim, uppercase, and check /^[A-Z]{2}$/ before calling.
- If you have a country name or ISO-3 code, map it to ISO-2 (lookup table) before invoking.
- Ensure callers don't pass undefined when the field is optional — default to a valid code or skip the call.
- For API entry points, reject invalid countryCode with a ValidationError at the request boundary, mirroring get-resilience-indicators.ts.
Example fix
// before
await ensureResilienceScoreGenerationCached(userInput.country); // may be 'Brazil' or ''
// after
const iso2 = String(userInput.country ?? '').trim().toUpperCase();
if (!/^[A-Z]{2}$/.test(iso2)) throw new ValidationError([{ field: 'countryCode', description: 'countryCode must be a 2-letter ISO 3166-1 alpha-2 code' }]);
await ensureResilienceScoreGenerationCached(iso2); Defensive patterns
Strategy: validation
Validate before calling
function toIso2(v) { const s = String(v ?? '').trim().toUpperCase(); return /^[A-Z]{2}$/.test(s) ? s : null; }
const cc = toIso2(input.country);
if (!cc) throw new Error('countryCode must be a 2-letter ISO 3166-1 alpha-2 code'); Type guard
function isIso2(v: unknown): v is string {
return typeof v === 'string' && /^[A-Z]{2}$/.test(v.trim().toUpperCase());
} Try / catch
try {
await ensureResilienceScoreGenerationCached(cc);
} catch (err) {
if (err.message.includes('A valid country code is required')) {
return badRequest({ field: 'countryCode', description: 'must be ISO-2' });
}
throw err;
} Prevention
- Normalize (trim + uppercase) all country inputs at the boundary
- Maintain a name/ISO-3 → ISO-2 lookup for user-supplied data
- Never pass optional/possibly-undefined codes into the generation path
- Add unit tests for '', 'usa', lowercase, and whitespace inputs
When it happens
Trigger: Calling ensureResilienceScoreGenerationCached('') , with undefined/null, with a 3-letter code like 'USA', with lowercase-only garbage that fails normalization, or with codes containing whitespace/numbers/dashes. Unlike ensureResilienceScoreCached (which returns a blank score), the *generation* wrapper throws.
Common situations: 1) A caller passes an unvalidated user-supplied country string (e.g., from a URL query param or country name like 'Brazil'); 2) an upstream seed/manifest produces an empty code; 3) code refactors pass full country names or ISO-3 codes where ISO-2 is required.
Related errors
- fromIso2 and toIso2 must be valid 2-letter ISO country codes
- iso2 must be a 2-letter uppercase ISO country code
- iso2 must be a 2-letter uppercase ISO country code
- country must be an ISO 3166-1 alpha-2 country code, e.g. "UA
- Could not resolve ${JSON.stringify(echoCountryInput(raw))} t
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/d5796f00babf79bb.
Report an issue: GitHub.