ruvnet/ruflo · error · ProviderUnavailableError

PROVIDER_UNAVAILABLE

PROVIDER_UNAVAILABLE

Error message

Provider ollama is unavailable

What it means

OllamaProvider treats status 0 (fetch-level network failure) or an error body containing 'connection' as ProviderUnavailableError with the hint 'Ensure Ollama is running: ollama serve'. Ollama is a local daemon (default http://localhost:11434), so this fires when the server is not reachable rather than when a request is malformed. Marked retryable (503).

Source

Thrown at v3/@claude-flow/providers/src/ollama-provider.ts:393

      finishReason: data.done ? 'stop' : 'length',
      latency: data.total_duration ? data.total_duration / 1e6 : undefined, // Convert ns to ms
    };
  }

  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('ollama', {
        message,
        hint: 'Ensure Ollama is running: ollama serve',
      });
    }

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

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Start the daemon: `ollama serve`, then verify with curl http://localhost:11434/api/tags
  2. Point config.apiUrl at the real host:port - from Docker use http://host.docker.internal:11434 (not localhost)
  3. Run Ollama as a systemd/launchd service so it survives reboots
  4. For remote daemons, ensure OLLAMA_HOST is set server-side and the port is reachable (no firewall drop)

Example fix

// before
const provider = new OllamaProvider({
  name: 'ollama',
  config: { model: 'llama3.1:8b', apiUrl: 'http://localhost:11434' }, // app runs in Docker
});

// after
const provider = new OllamaProvider({
  name: 'ollama',
  config: { model: 'llama3.1:8b', apiUrl: 'http://host.docker.internal:11434' },
});
Defensive patterns

Strategy: validation

Validate before calling

async function ollamaUp(apiUrl = 'http://localhost:11434'): Promise<boolean> {
  try {
    const ctrl = new AbortController();
    const t = setTimeout(() => ctrl.abort(), 2000);
    const r = await fetch(`${apiUrl}/api/tags`, { signal: ctrl.signal });
    clearTimeout(t);
    return r.ok;
  } catch {
    return false; // daemon not reachable -> expect PROVIDER_UNAVAILABLE
  }
}

Type guard

import { ProviderUnavailableError } from './types.js';
function isOllamaUnavailable(e: unknown): e is ProviderUnavailableError {
  return e instanceof ProviderUnavailableError && e.provider === 'ollama';
}

Try / catch

try {
  return await ollamaProvider.complete(req);
} catch (e) {
  if (isOllamaUnavailable(e)) {
    return manager.complete(req, cloudProvider); // fail over to a cloud provider
  }
  throw e;
}

Prevention

When it happens

Trigger: complete()/streamComplete() while the ollama daemon is not running; config.apiUrl pointing at the wrong host/port; a Docker container reaching 'localhost' instead of the host's Ollama; OLLAMA_HOST changed on the server.

Common situations: Forgot `ollama serve` after a reboot; running the app in Docker where localhost is the container itself; Ollama bound to 127.0.0.1 only while the app runs on another host; port changed from 11434.

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/8db7052eeea3c701. Report an issue: GitHub.