ruvnet/ruflo · error · ProviderUnavailableError

PROVIDER_UNAVAILABLE

PROVIDER_UNAVAILABLE

Error message

Provider custom is unavailable

What it means

RuVectorProvider.handleErrorResponse classifies a failure as connection-level when response.status === 0 or the error text contains 'connection', and throws ProviderUnavailableError (code PROVIDER_UNAVAILABLE, statusCode 503, retryable=true) with the hint 'Start RuVector server: npx @ruvector/ruvllm serve'. This error means 'server not reachable', not 'bad request' — it is the signal ProviderManager's fallback logic keys on.

Source

Thrown at v3/@claude-flow/providers/src/ruvector-provider.ts:634

        router: data.router_metrics,
      },
    };
  }

  private async handleErrorResponse(response: Response): Promise<never> {
    const errorText = await response.text();
    let errorData: { error?: string };

    try {
      errorData = JSON.parse(errorText);
    } catch {
      errorData = { error: errorText };
    }

    const message = errorData.error || 'Unknown error';

    if (response.status === 0 || message.includes('connection')) {
      throw new ProviderUnavailableError('custom', {
        message,
        hint: 'Start RuVector server: npx @ruvector/ruvllm serve',
      });
    }

    throw new LLMProviderError(
      message,
      `RUVECTOR_${response.status}`,
      'custom',
      response.status,
      true,
      errorData
    );
  }

  /**
   * Get SONA learning metrics
   */

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Start the server: npx @ruvector/ruvllm serve
  2. Confirm the provider's baseUrl/port matches the serving process (curl the baseUrl root or /v1/sona/metrics)
  3. In Docker: publish the port and address the container by service name, not localhost
  4. Configure a second provider in ProviderManager so fallback engages when ruvector is unavailable

Example fix

# before: server never started, only ruvector configured
# → Provider custom is unavailable

# after: start the server and keep a fallback provider
npx @ruvector/ruvllm serve &
providers: [
  { provider: 'ruvector', baseUrl: 'http://localhost:8080' },
  { provider: 'openai' },
]
Defensive patterns

Strategy: fallback

Validate before calling

import { ProviderUnavailableError } from './types.js';
// optional pre-flight probe before a batch of calls
async function ruvectorUp(baseUrl: string): Promise<boolean> {
  try {
    const res = await fetch(`${baseUrl}/v1/sona/metrics`);
    return res.status < 500; // any answer means the server is reachable
  } catch {
    return false;
  }
}

Type guard

import { isLLMProviderError } from './types.js';
function isRuvectorUnavailable(e: unknown): boolean {
  return isLLMProviderError(e) && e.code === 'PROVIDER_UNAVAILABLE' && e.provider === 'custom';
}

Try / catch

try {
  return await ruvector.complete(request);
} catch (e) {
  if (isRuvectorUnavailable(e)) {
    return await fallbackProvider.complete(request); // or let ProviderManager's completWithFallback do this
  }
  throw e;
}

Prevention

When it happens

Trigger: Any RuVector HTTP call while the server process is down; baseUrl pointing at the wrong port/host so the connection is refused; a gateway between client and server reporting a connection failure in its error body.

Common situations: Forgot to start the RuVector server before running the swarm; Docker container port not published or using localhost from another container; stale host in config after the server moved; CI environments with no local model server at all.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/daf53547d30b350f. Report an issue: GitHub.