koala73/worldmonitor · error · McpSourceUnavailableError

No hotspot-escalation input feeds are available

Error message

No hotspot-escalation input feeds are available

What it means

McpSourceUnavailableError thrown by requireAnyInput (api/mcp/registry/analysis-tools.ts:173) for the hotspot-escalation analysis tool: all of its input feeds read null, so escalation analysis cannot run. The typed fields carry unavailable_inputs (cache misses) and failed_inputs (Redis read errors) for faithful downstream reporting via dispatch.

Solutions

  1. Classify via error.data: failed_inputs → Redis health; unavailable_inputs → producer/seed state
  2. Confirm the hotspot-escalation input keys on /api/health
  3. Retry after the next producer publish window
  4. Run the corresponding seeds or restart the producer if keys are absent
Defensive patterns

Strategy: retry

Validate before calling

const health = await fetch('https://<host>/api/health').then(r => r.json());
if (hotspotInputKeys.some(k => !health?.datasets?.[k])) defer('hotspot inputs unseeded');

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling the hotspot-escalation tool when every input cache key returns null — producer pipelines for its inputs are down, keys expired or were evicted, seeds never ran, or Redis reads failed across the board.

Common situations: Upstream intelligence producer outage. Fresh deploy pre-seed. Upstash degradation window. Keys evicted under memory pressure between producer cycles.

Related errors


AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-08-21). Data as JSON: /api/errors/11127de37783f2ad. Report an issue: GitHub.

Appendix: source

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

      stale: evaluated.stale || unavailableInputs.length > 0,
      unavailable_inputs: unavailableInputs,
      failed_inputs: failedInputs,
    },
  };
}

const ANALYSIS_CACHE_STATUS_PROPERTIES = {
  unavailable_inputs: {
    type: 'array',
    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 {

View on GitHub (pinned to 7d06c8633d)