ruvnet/ruflo · error · ModelNotFoundError

MODEL_NOT_FOUND

MODEL_NOT_FOUND

Error message

Model ${model} not found

What it means

OpenAIProvider maps HTTP 404 to ModelNotFoundError (code MODEL_NOT_FOUND, non-retryable), reporting this.config.model in the message. It fires when the model id does not exist for your account: a typo, a retired model (OpenAI deprecates older models), or a gated model your key cannot access. Note the handler reads config.model, so if a request overrode the model per-call, the message can name the configured model rather than the one actually requested.

Source

Thrown at v3/@claude-flow/providers/src/openai-provider.ts:478

    } catch {
      errorData = { error: { message: errorText } };
    }

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

    switch (response.status) {
      case 401:
        throw new AuthenticationError(message, 'openai', errorData);
      case 429:
        const retryAfter = response.headers.get('retry-after');
        throw new RateLimitError(
          message,
          'openai',
          retryAfter ? parseInt(retryAfter) : undefined,
          errorData
        );
      case 404:
        throw new ModelNotFoundError(this.config.model, 'openai', errorData);
      default:
        throw new LLMProviderError(
          message,
          `OPENAI_${response.status}`,
          'openai',
          response.status,
          response.status >= 500,
          errorData
        );
    }
  }
}

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Use a current model id - list what your key can see: curl -H 'Authorization: Bearer $OPENAI_API_KEY' https://api.openai.com/v1/models
  2. Fix exact spelling and dashes: 'gpt-4o', not 'gpt4o' or 'GPT-4O'
  3. If you pass request.model per call, also keep config.model valid - the 404 handler reports config.model, which can mislead
  4. For gated models, request access in the dashboard or switch to an available variant

Example fix

// before
config: { apiKey, model: 'gpt-4-32k' } // retired model -> Model not found (404)

// after
config: { apiKey, model: 'gpt-4o' } // verify against GET /v1/models for your key
Defensive patterns

Strategy: validation

Validate before calling

async function modelExistsForKey(model: string, apiKey: string): Promise<boolean> {
  const r = await fetch('https://api.openai.com/v1/models', {
    headers: { Authorization: `Bearer ${apiKey}` },
  });
  const { data } = await r.json();
  return Array.isArray(data) && data.some((m: { id: string }) => m.id === model);
}
// if (!await modelExistsForKey('gpt-4o', apiKey)) throw new Error('model unavailable for this key');

Type guard

import { ModelNotFoundError } from './types.js';
function isModelNotFound(e: unknown): e is ModelNotFoundError {
  return e instanceof ModelNotFoundError;
}

Try / catch

try {
  return await provider.complete(req);
} catch (e) {
  if (isModelNotFound(e)) {
    // deterministic: pick a known-good fallback model, do not retry the same id
    return provider.complete({ ...req, model: 'gpt-4o' });
  }
  throw e;
}

Prevention

When it happens

Trigger: complete() with model 'gpt-4-32k' or 'text-davinci-003' (retired), a typo like 'gpt4o', or a preview/gated model the key has no access to - OpenAI answers 404 and the provider raises this error.

Common situations: Code written against a model that was later deprecated; model id from an outdated tutorial; per-request model override while config.model holds a stale id; o1-style gated models without approval.

Related errors


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