musistudio/claude-code-router · warning
OpenRouter endpoints request timed out after ${endpointFetch
Error message
OpenRouter endpoints request timed out after ${endpointFetchTimeoutMs}ms What it means
fetchModelEndpoints wraps fetch with an AbortController timeout of endpointFetchTimeoutMs; if the abort fires, the caught error is converted into this explicit timeout message (distinguishing it from genuine network errors).
Source
Thrown at packages/core/src/plugins/built-ins/openrouter-discount-provider-router.ts:360
endpointInflight.delete(cacheKey);
});
endpointInflight.set(cacheKey, promise);
return promise;
}
async function fetchModelEndpoints(url: string): Promise<unknown[]> {
const controller = new AbortController();
const timer = setTimeout(() => {
controller.abort(new Error(`OpenRouter endpoints request timed out after ${endpointFetchTimeoutMs}ms`));
}, endpointFetchTimeoutMs);
timer.unref?.();
let response: Response;
try {
response = await fetch(url, { signal: controller.signal });
} catch (error) {
if (controller.signal.aborted) {
throw new Error(`OpenRouter endpoints request timed out after ${endpointFetchTimeoutMs}ms`);
}
throw error;
} finally {
clearTimeout(timer);
}
if (!response.ok) {
const text = await response.text().catch(() => "");
throw new Error(`OpenRouter endpoints request failed (${response.status}): ${text.slice(0, 200)}`);
}
const payload = await response.json() as unknown;
const record = isRecord(payload) ? payload : {};
const data = isRecord(record.data) ? record.data : {};
const endpoints = Array.isArray(data.endpoints)
? data.endpoints
: Array.isArray(record.endpoints)
? record.endpointsView on GitHub (pinned to 99f24806c6)
Solutions
- Retry after the cooldown (the failure is cached) — transient timeouts often clear
- Increase endpointFetchTimeoutMs if your network is consistently slow
- Check proxy/VPN latency to openrouter.ai
Example fix
// before
{ endpointFetchTimeoutMs: 2000 }
// after
{ endpointFetchTimeoutMs: 15000 } Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
const isEndpointTimeout = (e: unknown): boolean => e instanceof Error && e.message.includes("timed out after"); Try / catch
try { return await loadModelEndpoints(model); } catch (e) { if (isEndpointTimeout(e)) return await withBackoff(() => loadModelEndpoints(model), 3); throw e; } Prevention
- Tune endpointFetchTimeoutMs to your network
- Wrap calls in exponential backoff with cooldown awareness
When it happens
Trigger: OpenRouter's /endpoints endpoint taking longer than the configured timeout; slow proxies; transient network stalls.
Common situations: Low timeout defaults in restrictive networks, corporate proxies adding latency, or OpenRouter degradation.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Grok CLI OAuth token refresh timed out after ${timeoutMs}ms.
- Grok CLI OIDC discovery timed out after ${timeoutMs}ms.
- OpenRouter providers request failed (${response.status}): ${
- Claude App profiles do not support agent arguments.
- Timed out waiting for ChatGPT response: + requestId
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/fb6adacb15c40038.
Report an issue: GitHub.