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
- Use a current model id - list what your key can see: curl -H 'Authorization: Bearer $OPENAI_API_KEY' https://api.openai.com/v1/models
- Fix exact spelling and dashes: 'gpt-4o', not 'gpt4o' or 'GPT-4O'
- If you pass request.model per call, also keep config.model valid - the 404 handler reports config.model, which can mislead
- 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
- Fetch the model list for your key at startup and validate configured ids against it
- Keep model ids in one constant/module so deprecations are a one-line change
- Remember the 404 handler reports config.model - keep config.model valid even when overriding per request
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
- Failed to import OpenAI
- Invalid completion type
- No endpoints configured. This build requires OpenAI-compatib
- Only 'openai' endpoint type is supported in this build
- OpenAI embedding failed: ${message}
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/4991e0b5634758e4.
Report an issue: GitHub.