ruvnet/ruflo · error
Circuit breaker ${this.name} is open
Error message
Circuit breaker ${this.name} is open What it means
Every provider built on BaseProvider wraps its doComplete/doStreamComplete calls in a CircuitBreaker. After `threshold` consecutive failures (default 5) the breaker flips to 'open' and this error is thrown immediately, without contacting the upstream API. Once `resetTimeout` ms (default 60000) elapse since the last failure, the next call transitions the breaker to 'half-open' and lets a trial request through.
Source
Thrown at v3/@claude-flow/providers/src/base-provider.ts:53
* Simple circuit breaker implementation
*/
class CircuitBreaker {
private failures = 0;
private lastFailure = 0;
private state: 'closed' | 'open' | 'half-open' = 'closed';
constructor(
private readonly name: string,
private readonly threshold: number = 5,
private readonly resetTimeout: number = 60000
) {}
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'open') {
if (Date.now() - this.lastFailure > this.resetTimeout) {
this.state = 'half-open';
} else {
throw new Error(`Circuit breaker ${this.name} is open`);
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onSuccess(): void {
this.failures = 0;
this.state = 'closed';
}
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Wait out the reset window (default 60 s) before the next call - the breaker then moves to half-open and allows one trial request; do not retry immediately
- Fix the underlying failures that opened it: inspect logs for the AuthenticationError / RateLimitError / LLMProviderError thrown just before the breaker opened
- Tune threshold and resetTimeout in the provider options if 5 failures / 60 s trips too easily for your traffic shape
- Recreate or re-initialize the provider to get a fresh breaker once you know upstream is healthy again
Example fix
// before
const provider = manager.getProvider('openai');
await provider.complete(req); // throws: Circuit breaker openai is open
// after - back off for the reset window, then retry once (half-open trial)
try {
await provider.complete(req);
} catch (e) {
if (e instanceof Error && e.message.includes('Circuit breaker')) {
await new Promise(r => setTimeout(r, 60_000));
await provider.complete(req);
} else {
throw e;
}
} Defensive patterns
Strategy: retry
Type guard
export function isCircuitBreakerOpen(e: unknown): boolean {
return e instanceof Error && /^Circuit breaker .+ is open$/.test(e.message);
} Try / catch
try {
return await provider.complete(req);
} catch (e) {
if (isCircuitBreakerOpen(e)) {
await new Promise(r => setTimeout(r, 60_000 + Math.random() * 5_000)); // resetTimeout + jitter
return provider.complete(req); // single half-open trial retry
}
throw e;
} Prevention
- Wrap complete()/streamComplete() in retry-with-backoff instead of tight loops
- Track provider healthCheck() and stop dispatching while a breaker is open
- Size config.timeout to the model's real latency so slow responses do not count as failures
- Tune threshold/resetTimeout to your request volume before shipping
When it happens
Trigger: Calling provider.complete() or provider.streamComplete() while that provider instance's breaker is 'open' and fewer than 60 s (resetTimeout) have passed since the last failure - e.g. the upstream API returned 429/5xx/timeout five times in a row and you retry a sixth time within the window.
Common situations: Sustained upstream outage or aggressive rate limiting that trips the breaker; a tight retry loop hammering the provider; config.timeout set too small so every call times out; one shared provider instance absorbing failures from many concurrent requests.
Related errors
- Circuit breaker is open. Service temporarily unavailable.
- Circuit breaker open for provider: ${provider}
- MCP server "${server.name}" is in cooldown (HTTP ${cd.status
- swarm state is busy; retry the outcome update
- provider call failed
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/081d95090df6fde8.
Report an issue: GitHub.