koala73/worldmonitor · error · McpSourceUnavailableError
Seeded world brief unavailable (${result.reason})
Error message
Seeded world brief unavailable (${result.reason}) What it means
Thrown by the get_world_brief MCP tool when projectSeededWorldBrief() rejected the insights payload with a bounded reason string. The function runs a chain of validation gates on the seeded world-brief snapshot (news:insights:v1): snapshot shape, non-empty brief text, status==='ok', at least one headline, 1-12 source records, and valid source URLs. The reason names WHICH gate fired, so 'empty-brief' (stale producer) and 'malformed-sources' (schema regression) need opposite responses. The error is an McpSourceUnavailableError with news:insights:v1 as the unavailable input.
Source
Thrown at api/mcp/registry/rpc-tools.ts:911
operation: 'bootstrap-insights',
tool: 'get_world_brief',
auth: context,
execution,
});
type BootstrapPayload = { data?: { insights?: unknown }; missing?: string[] };
const bootstrap = await insightsRes.json() as BootstrapPayload;
const rawInsights = bootstrap.data?.insights;
let insights: unknown = rawInsights;
if (typeof rawInsights === 'string') {
try {
insights = JSON.parse(rawInsights);
} catch {
insights = null;
}
}
const result = projectSeededWorldBrief(insights);
if ('reason' in result) {
throw new McpSourceUnavailableError(
`Seeded world brief unavailable (${result.reason})`,
['news:insights:v1'],
[],
);
}
return result.value;
},
_apiPaths: ['GET /api/infrastructure/v1/get-bootstrap-data'],
},
{
name: 'get_country_brief',
_outputBudgetBytes: 65536,
description: 'AI-generated per-country intelligence brief. Produces an LLM-analyzed geopolitical and economic assessment for the given country. Supports analytical frameworks for structured lenses. Returns groundingStories alongside sources: the digest articles used to ground the brief, each with corroborationCount, mentionCount, and lifecycle storyPhase, so an agent can weigh how well-corroborated the underlying reporting is.',
inputSchema: {
type: 'object',
properties: {
country_code: { type: 'string', description: 'ISO 3166-1 alpha-2 country code, e.g. "US", "DE", "CN", "IR"' },
framework: { type: 'string', description: 'Optional analytical framework instructions to shape the analysis lens (e.g. Ray Dalio debt cycle, PMESII-PT)' },View on GitHub (pinned to ffec79ac33)
Solutions
- Read the reason from the error message (inside the parentheses) — it identifies the exact gate: 'empty-brief' and 'status-not-ok' point to a producer/LLM issue; 'missing-sources'/'malformed-sources' point to a source-extraction issue; 'no-headlines' points to a topStories issue.
- Inspect the news:insights:v1 key in Redis and verify the worldBrief, status, topStories, and worldBriefSources fields against the gates in projectSeededWorldBrief.
- Re-run the world-brief producer/seeder to regenerate a fresh, valid snapshot.
- Retry after the insights seed cadence — a transient degraded snapshot is overwritten on the next cycle.
Defensive patterns
Strategy: retry
Validate before calling
// Check that the insights snapshot is fresh and valid before calling get_world_brief
const health = await fetch('/api/health').then(r => r.json());
const insightsMeta = health.seedMeta?.['seed-meta:news:insights'];
if (!insightsMeta || Date.now() - insightsMeta.ts > insightsMeta.maxStaleMs) {
throw new Error('World brief producer is stale; retry after seed cycle');
} Type guard
function isMcpSourceUnavailableError(e: unknown): e is { unavailableInputs: string[]; failedInputs: string[] } & Error {
return e instanceof Error && (e as any).name === 'McpSourceUnavailableError';
} Try / catch
try {
const brief = await callMcpTool('get_world_brief', {});
} catch (e) {
if (isMcpSourceUnavailableError(e) && e.message.includes('Seeded world brief unavailable')) {
const reason = e.message.match(/\((.*)\)/)?.[1];
if (reason === 'empty-brief' || reason === 'status-not-ok') {
// Producer degraded — retry after seed cycle
await backoffRetry(120_000);
} else {
// Schema regression (malformed-sources, missing-sources) — do not retry blindly
logSchemaIssue(reason);
}
} else throw e;
} Prevention
- Monitor the world-brief LLM producer for degraded runs (empty brief, error status).
- Track the specific reason values in alerts — 'empty-brief'/'status-not-ok' need producer attention; 'malformed-*' needs schema attention.
- Cache the last valid world brief as a degraded fallback during producer outages.
When it happens
Trigger: Calling get_world_brief when the insights seeder produced a payload that fails one of the gates: reason='empty-brief' (worldBrief string is blank), 'status-not-ok' (producer set status to an error value), 'no-headlines' (topStories empty), 'missing-sources' (worldBriefSources absent, empty, or >12), 'malformed-sources' (sources lack any valid URL), 'malformed-snapshot' (raw is not a record), or a snapshotRejection reason (staleness/shape failure from insightsSnapshotRejection).
Common situations: The world-brief LLM producer ran but wrote a degraded snapshot (empty brief text, error status); a producer deploy changed the snapshot shape; the brief was generated but source extraction failed leaving zero usable citations; staleness — the snapshot is older than the producer's acceptance window.
Related errors
- serverUrl DNS resolution returned no addresses
- No event feeds are available for exposure enrichment
- No digest input feeds are available
- No hotspot-escalation input feeds are available
- The submarine-cable catalog is unavailable
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/ec962e3301ea4c25.
Report an issue: GitHub.