koala73/worldmonitor · error · McpSourceUnavailableError

No primary military feeds are available

Error message

No primary military feeds are available

What it means

McpSourceUnavailableError thrown by requireAnyInput (api/mcp/registry/analysis-tools.ts:173) for tools needing primary military feeds: every military input cache payload was null. The typed fields carry unavailable_inputs and failed_inputs so the caller can tell a genuine data gap (feeds never seeded / expired) from Redis read failures.

Source

Thrown at api/mcp/registry/analysis-tools.ts:179

    items: { type: 'string' },
    description: 'Required cache keys that were missing or unreadable; their contribution is not treated as quiet.',
  },
  failed_inputs: {
    type: 'array',
    items: { type: 'string' },
    description: 'Subset of unavailable_inputs whose Redis read failed rather than returning a genuine miss.',
  },
} as const;

type AnalysisFreshness = Awaited<ReturnType<typeof readCachesWithFreshness>>['freshness'];

function requireAnyInput(
  payloads: unknown[],
  freshness: AnalysisFreshness,
  message: string,
): void {
  if (payloads.every((value) => value === null)) {
    throw new McpSourceUnavailableError(
      message,
      freshness.unavailable_inputs,
      freshness.failed_inputs,
    );
  }
}

function resolveLimit(raw: unknown, fallback: number): number {
  if (raw === undefined || raw === null) return fallback;
  const parsed = Math.round(Number(raw));
  if (!Number.isFinite(parsed)) return fallback;
  if (parsed <= 0) return Number.POSITIVE_INFINITY;
  return parsed;
}

// Keep the analysis schemas aligned with cacheEnvelope(). Content age is not a
// universal rule: evaluateFreshness() applies it only to checks that explicitly
// declare honorContentAge.

View on GitHub (pinned to 9361220cc0)

Solutions

  1. Distinguish miss vs failure via error.data (unavailable_inputs vs failed_inputs)
  2. Confirm military feed keys are fresh on the health endpoint
  3. Retry during/after the next military producer cycle
  4. Seed the military keys or restart their producer if health shows them absent
Defensive patterns

Strategy: retry

Validate before calling

const health = await fetch('https://<host>/api/health').then(r => r.json());
const militaryReady = militaryFeedKeys.every(k => health?.datasets?.[k]?.fresh !== false);

Type guard

function isSourceUnavailable(e) {
  return e?.name === 'McpSourceUnavailableError' || Array.isArray(e?.data?.unavailable_inputs);
}

Try / catch

try {
  await client.callTool(militaryAnalysisTool, args);
} catch (e) {
  if (isSourceUnavailable(e) && e.data?.failed_inputs?.length) return retryWithBackoff(call, 3);
  if (isSourceUnavailable(e)) return retryAfter(producerCadence);
  throw e;
}

Prevention

When it happens

Trigger: Calling a military analysis tool while all military feed cache keys (e.g. conflict/military event stores) read null — military producer pipelines down, keys evicted/expired, environment never seeded, or Upstash read errors.

Common situations: Military data producer job failed upstream. Deployment ordering issue where MCP ships before seeds. Upstash outage window. Eviction policy pressure removing the military keys.

Related errors


AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-08-21). Data as JSON: /api/errors/81414a6f687a580a. Report an issue: GitHub.