koala73/worldmonitor · error · ValidationError
iso2 must be a 2-letter uppercase ISO country code
Error message
iso2 must be a 2-letter uppercase ISO country code
What it means
getCountryVulnerabilities normalizes req.iso2 (trim + uppercase) and requires /^[A-Z]{2}$/ before looking up the country in the vulnerability cohort payload. Invalid values throw this ValidationError on field 'iso2'.
Source
Thrown at server/worldmonitor/supply-chain/v1/get-country-vulnerabilities.ts:30
VULNERABILITY_COHORT_KEY,
countryVulnerabilityShardKey,
enforceCommodityRedistributionPolicy,
hasCurrentRedistributionPolicy,
isMatchingShard,
locateEntityShard,
mapCommodityVulnerability,
type RawVulnerabilityCohort,
type RawCountryShard,
stringValue,
} from './_vulnerability-projection';
export async function getCountryVulnerabilities(
ctx: ServerContext,
req: GetCountryVulnerabilitiesRequest,
): Promise<GetCountryVulnerabilitiesResponse> {
const iso2 = (req.iso2 || '').trim().toUpperCase();
if (!/^[A-Z]{2}$/.test(iso2)) {
throw new ValidationError([{ field: 'iso2', description: 'iso2 must be a 2-letter uppercase ISO country code' }]);
}
const persistedPayload = await getCachedJson(VULNERABILITY_COHORT_KEY, true)
.catch(() => null) as RawVulnerabilityCohort | null;
const payload = hasCurrentRedistributionPolicy(persistedPayload) ? persistedPayload : null;
let country = payload?.countries?.[iso2];
let shardUnavailable = false;
if (payload && !payload.countries) {
const located = locateEntityShard(payload, payload.countryIds, iso2, countryVulnerabilityShardKey);
if (located.status === 'unavailable') {
shardUnavailable = true;
} else if (located.status === 'read') {
const shard = await getCachedJson(located.key, true)
.catch(() => null) as RawCountryShard | null;
if (isMatchingShard(payload, shard) && shard?.country?.iso2 === iso2) country = shard.country;
else shardUnavailable = true;
}
}View on GitHub (pinned to 9361220cc0)
Solutions
- Send an uppercase 2-letter ISO 3166-1 alpha-2 code ('BR', not 'BRA')
- Trim and uppercase client-side (server does this anyway)
- Validate with /^[A-Z]{2}$/ before the call
- Convert alpha-3/name inputs to alpha-2 via a lookup map before invoking
Example fix
// before
await getCountryVulnerabilities({ iso2: 'BRA' })
// after
const iso2 = String(raw).trim().toUpperCase();
if (!/^[A-Z]{2}$/.test(iso2)) throw new Error('iso2 must be alpha-2');
await getCountryVulnerabilities({ iso2: iso2 }) Defensive patterns
Strategy: validation
Validate before calling
function normalizeIso2(v) {
const code = String(v || '').trim().toUpperCase();
return /^[A-Z]{2}$/.test(code) ? code : null;
} Type guard
function isIso2(v) {
return typeof v === 'string' && /^[A-Z]{2}$/.test(v);
} Try / catch
try {
return await getCountryVulnerabilities({ iso2 });
} catch (e) {
if (e.name === 'ValidationError' && e.field === 'iso2') {
return null;
}
throw e;
} Prevention
- Use alpha-2 codes consistently across datasets
- Validate iso2 format at form level
- Normalize case/whitespace before sending
- Maintain an alpha-3 -> alpha-2 mapping for legacy data
When it happens
Trigger: Passing empty/missing iso2, ISO-3 codes ('BRA'), full country names, numeric country codes, or lowercase codes (lowercase is accepted because of toUpperCase, but wrong length is not).
Common situations: Clients using UN M49 numeric codes or FIPS codes; form fields allowing free text; mixing alpha-2 and alpha-3 datasets.
Related errors
- countryCode must be a 2-letter ISO 3166-1 alpha-2 code
- 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
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/51c0b75a4521efa8.
Report an issue: GitHub.