koala73/worldmonitor · error · Error
get-country-intel-brief HTTP ${res.status}${code ? `: ${code
Error message
get-country-intel-brief HTTP ${res.status}${code ? `: ${code}` : ''} What it means
Thrown by the get_country_intel_brief MCP tool when the downstream /api/intelligence/v1/get-country-intel-brief endpoint returned a non-OK HTTP status. Before this throw, the code checks for a BillingDenialError (re-thrown separately so billing contract is preserved), then extracts a bounded error detail (max 120 chars) from the JSON body's error field or falls back to stripped HTML/text. The message includes the HTTP status and the truncated code so Sentry titles stay bounded.
Source
Thrown at api/mcp/registry/rpc-tools.ts:1056
});
if (!res.ok) {
throwIfBillingDenial(res, 'get-country-intel-brief');
// Surface the gateway's error code in the thrown message so Sentry
// groups the failure by root cause, not just status. Body reads are
// best-effort; a read failure must not mask the HTTP status.
const detail = await res.text().catch(() => '');
let code = '';
// `error` is usually a string (for example,
// `invalid_internal_mcp_signature`), but stringify non-string shapes so
// object envelopes remain readable. Bound both paths so Sentry titles
// cannot bloat on a long body.
try {
const error = (JSON.parse(detail) as { error?: unknown }).error ?? '';
code = (typeof error === 'string' ? error : JSON.stringify(error)).slice(0, 120);
} catch {
code = detail.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 120);
}
throw new Error(`get-country-intel-brief HTTP ${res.status}${code ? `: ${code}` : ''}`);
}
const result = await res.json() as Record<string, unknown>;
const resultSources = collectMcpBriefSources(Array.isArray(result.sources) ? result.sources as DigestItemForBrief[] : [], 6);
// groundingStories stays [] when the 2 s digest fetch failed above, which
// is the honest signal: the brief was written without that grounding.
return { ...result, sources: resultSources.length > 0 ? resultSources : sources, groundingStories };
},
// METHOD DRIFT: _execute POSTs above but OpenAPI declares only GET on this
// path (verified against docs/api/IntelligenceService.openapi.json). The
// gateway routes by path, not method, so POST works at runtime. We declare
// GET here because OpenAPI is the parity test's source-of-truth — fixing
// the spec to add POST (or migrating the handler to GET) is out of scope.
_apiPaths: [
"GET /api/intelligence/v1/get-country-intel-brief",
],
},
{
name: 'get_country_risk',View on GitHub (pinned to ffec79ac33)
Solutions
- Read the HTTP status from the error message: 401/403 — check auth context and HMAC signing; 429 — retry with backoff; 5xx — retry after a delay (LLM provider issue); 400 — verify country_code is a valid ISO 3166-1 alpha-2 code.
- Retry with exponential backoff for 429 and 5xx — these are typically transient.
- Verify the buildAuthHeaders context (proxy_id, secret) is valid and not expired if you see 401/403.
- Call a different country_code to determine if the failure is country-specific or systemic.
Defensive patterns
Strategy: retry
Validate before calling
// Validate inputs and auth before calling get_country_intel_brief
if (!/^[A-Z]{2}$/.test(countryCode)) {
throw new Error('country_code must be a valid ISO 3166-1 alpha-2 code');
}
// Verify auth context is not expired before the call
if (context.expiresAt && Date.now() > context.expiresAt) {
throw new Error('Auth context expired; refresh before calling');
} Type guard
function isCountryIntelBriefHttpError(e: unknown): e is { status: number } & Error {
return e instanceof Error && /get-country-intel-brief HTTP \d+/.test(e.message);
} Try / catch
try {
const brief = await callMcpTool('get_country_intel_brief', { country_code: 'US' });
} catch (e) {
if (e instanceof Error) {
const status = e.message.match(/HTTP (\d+)/)?.[1];
if (status === '429' || (status && Number(status) >= 500)) {
await exponentialBackoffRetry(); // transient
} else if (status === '401' || status === '403') {
refreshAuthContext(); // auth issue
} else {
throw e; // 400 etc — input problem
}
} else throw e;
} Prevention
- Validate country_code is a real ISO 3166-1 alpha-2 code before calling.
- Ensure the auth context (proxy_id, secret) is fresh and the HMAC signature is valid.
- Implement exponential backoff for 429/5xx responses — the LLM provider may be rate-limited.
When it happens
Trigger: The country intel brief handler returned 4xx/5xx — common causes: 401/403 (auth/HMAC failure on the gateway RPC), 429 (rate limit), 500 (LLM provider failure during brief generation), 502/504 (upstream LLM timeout), or a 400 (invalid country_code). The billing-denial path (402 with billing code) is handled earlier and never reaches this throw.
Common situations: LLM provider outage or rate limit causing the brief generation to fail; an expired or invalid MCP signature/HMAC causing 401/403; an unsupported country_code causing a 400; a gateway deployment issue where the route is temporarily unavailable.
Related errors
- get-vessel-snapshot HTTP ${res.status}${detail ? ` — ${detai
- get-china-decision-signals returned no canonical payload
- Airspace data unavailable: both civilian and military source
- HTTP %d: %s
- serverUrl host is not allowed
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/4ca722721e64ed87.
Report an issue: GitHub.