How to Debug OmniRoute Routing Issues Using the Circuit Breaker Dashboard
You can debug OmniRoute routing failures by querying the /api/monitoring/health endpoint to inspect real-time provider circuit breaker states, failure counts, and automatic recovery timestamps.
OmniRoute implements resilient request routing through layered protection mechanisms that isolate failing providers. When upstream services return HTTP 5xx errors or time out, the system activates circuit breakers to prevent cascading failures. The circuit breaker dashboard exposes internal health metrics through a dedicated API endpoint, allowing you to diagnose why requests are being dropped or rerouted.
Understanding OmniRoute's Circuit Breaker Architecture
OmniRoute protects request routing with three distinct resilience layers: provider circuit breakers, connection cooldowns, and model lockouts. When a provider repeatedly fails, the circuit breaker flips to OPEN and temporarily blocks all traffic to that provider while the routing engine falls back to healthy candidates.
The core implementation resides in src/shared/utils/circuitBreaker.ts, which manages state tracking, back-off timers, and failure thresholds. According to the Resilience Guide in docs/architecture/RESILIENCE_GUIDE.md, these mechanisms work together to ensure that transient outages do not degrade overall system availability.
Accessing the Circuit Breaker Dashboard
The dashboard exposes provider health data through the internal endpoint /api/monitoring/health. The route handler is implemented in src/app/api/monitoring/health/route.ts, which serializes the in-memory breaker states into a JSON payload.
When you query this endpoint, the response contains an array of provider objects with the following diagnostic fields:
provider: Human-readable identifier (e.g.,openai,anthropic).circuitBreakerState: Current state as"CLOSED","OPEN", or"HALF_OPEN".circuitOpenUntil: Epoch-millisecond timestamp indicating when the OPEN state expires.failureCount: Consecutive failures that triggered the current state.resetTimeoutMs: Configured back-off timeout for this provider.lastError: The most recent error message (e.g., "504 Gateway Timeout").
Interpreting Dashboard Metrics
Circuit Breaker States
The dashboard reports three distinct states that indicate provider health:
- CLOSED: The provider is healthy and accepting traffic. If routing issues persist while the state is closed, investigate rate limits or model lockouts instead.
- OPEN: The provider is blocked due to consecutive failures. Check
circuitOpenUntilto determine when automatic recovery will occur. - HALF_OPEN: The system is probing the provider with a test request. A successful probe closes the circuit; a failure reopens it.
Key Diagnostic Fields
The lastError field reveals the root cause of the failure streak, such as "502 Bad Gateway" or connection timeouts. Correlate this with failureCount to determine if the provider is approaching its threshold (OAuth providers default to 3 failures, API-key providers to 5, as defined in src/shared/config/constants.ts).
The circuitOpenUntil timestamp implements lazy recovery, ensuring the provider remains isolated until the configured resetTimeoutMs elapses.
Step-by-Step Debugging Workflow
Follow this systematic approach to diagnose routing anomalies using the dashboard:
-
Query the health endpoint using
curl http://localhost:20128/api/monitoring/healthor fetch it from your browser console. -
Locate the target provider in the JSON response array.
-
Check
circuitBreakerState:- If
CLOSED, examinelastErrorand request logs for non-circuit issues. - If
OPEN, note thecircuitOpenUntiltimestamp to estimate recovery time. - If
HALF_OPEN, wait for the probe to complete or investigate immediate failures.
- If
-
Inspect
lastErrorto identify whether the issue stems from network timeouts, HTTP errors, or authentication failures. -
Correlate with request logs in
open-sse/utils/requestLogger.tsto confirm the request was short-circuited before reaching the upstream. -
Adjust configuration if thresholds are too aggressive by modifying environment variables or constants in
src/shared/config/constants.ts.
Manual Reset and Configuration Tuning
If a circuit breaker is open but you have verified the provider is healthy, you can force recovery by invoking resetAllCircuitBreakers() from src/shared/utils/circuitBreaker.ts. This function clears the in-memory state immediately, though the breaker will reopen if failures persist.
Provider-specific thresholds reside in src/shared/config/constants.ts, where OAuth providers default to 3 consecutive failures and API-key providers default to 5. Override these values via environment variables to tune sensitivity based on your reliability requirements.
Practical Code Examples
Fetch the dashboard programmatically using Node.js:
import fetch from 'node-fetch';
async function getCircuitStatus() {
const res = await fetch('http://localhost:20128/api/monitoring/health');
const data = await res.json();
data.providers.forEach(p => {
console.log(
`${p.provider}: ${p.circuitBreakerState}` +
(p.circuitBreakerState === 'OPEN' ? ` (unblocks @ ${new Date(p.circuitOpenUntil)})` : '')
);
});
}
getCircuitStatus();
Quick command-line inspection with curl and jq:
curl -s http://localhost:20128/api/monitoring/health | jq .
Render provider status in a React component:
import useSWR from 'swr';
export function ProviderBadge({ provider }: { provider: string }) {
const { data } = useSWR('/api/monitoring/health', url => fetch(url).then(r => r.json()));
const info = data?.providers?.find(p => p.provider === provider);
if (!info) return null;
const color = info.circuitBreakerState === 'OPEN' ? 'red' : 'green';
return <span style={{ color }}>{info.circuitBreakerState}</span>;
}
Summary
- Query
/api/monitoring/health(implemented insrc/app/api/monitoring/health/route.ts) to retrieve real-time circuit breaker states for all providers. - Interpret
circuitBreakerStatevalues (CLOSED,OPEN,HALF_OPEN) to determine if routing issues stem from circuit isolation or other factors. - Use
circuitOpenUntilandlastErrorto diagnose recovery timelines and root causes. - Invoke
resetAllCircuitBreakers()fromsrc/shared/utils/circuitBreaker.tsfor manual recovery after verifying provider health. - Adjust failure thresholds in
src/shared/config/constants.tsto balance resilience against sensitivity.
Frequently Asked Questions
How do I know if a routing failure is caused by a circuit breaker or a rate limit?
Check the circuitBreakerState field in the health endpoint response. If the state is CLOSED, the provider is healthy and the failure likely stems from rate limiting or model lockouts. If the state is OPEN or HALF_OPEN, the circuit breaker has isolated the provider due to consecutive errors, which you can verify by inspecting the lastError field for HTTP 5xx or timeout messages.
What is the difference between HALF_OPEN and OPEN states?
An OPEN circuit completely blocks traffic to the provider until the circuitOpenUntil timestamp passes. HALF_OPEN indicates the system is testing the provider with a single probe request. If the probe succeeds, the state returns to CLOSED; if it fails, the circuit reverts to OPEN with a refreshed timeout. This allows automatic recovery without manual intervention.
Can I manually close a circuit breaker before the timeout expires?
Yes. You can manually reset the circuit by calling resetAllCircuitBreakers() from src/shared/utils/circuitBreaker.ts, which clears the in-memory state immediately. However, only use this after confirming the provider is genuinely healthy, as premature reset will cause the breaker to reopen quickly if failures persist.
Where are the circuit breaker thresholds configured?
Default failure thresholds are defined in src/shared/config/constants.ts, with OAuth providers typically set to 3 failures and API-key providers to 5. You can override these values through environment variables to adjust how quickly the system isolates unreliable providers based on your specific reliability requirements.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →