Model Not Found or "Does Not Exist": Diagnose the 404 in Two Minutes
Usually nothing was retired: the name, the endpoint path or the key's access does not line up. One list request with the same key and base_url narrows it down.
1. Start with the model list, using the same key and base_url
Nearly every OpenAI-compatible endpoint exposes `GET /v1/models`. Call it with the exact key and base_url your failing code uses — not the ones in your notes, not a colleague's — and search the response for your model string. A one-liner is enough: `curl -s $BASE_URL/models -H "Authorization: Bearer $KEY" | grep -o '"id": *"[^"]*"'`. This splits the problem in half in under a minute. If the string is missing, you are looking at a naming, endpoint or access problem, and the rest of this page tells you which. If the string is present and calls still fail, the name is fine and the problem is the route or a tool in the middle. Save that output: it is the reference you will diff against later.
2. Read three facts from the raw response
SDKs and apps often rewrite errors into something vaguer, so look underneath. You need three things: the HTTP status, the response body, and the full URL that was called. A JSON body whose error code reads `model_not_found` (or similar) confirms the model lookup failed. An HTTP 401 usually points to authentication; a 403 may involve permissions, account policy or other access restrictions. An HTML 404 suggests a path, proxy or routing problem; inspect the full URL and response headers before drawing a conclusion about model lookup. For an HTTP 400, read the detailed error: it can identify an invalid name or an unsupported request parameter. Thirty seconds of printing these three facts beats an hour of guessing.
3. The base_url trap: a missing or doubled /v1
Some clients expect base_url to end in `/v1`; others append it for you. Get it wrong and you end up calling `/chat/completions` without the version prefix, or `/v1/v1/chat/completions`. The confusing part is that the reply is not always a plain 404: a gateway may route the odd path to a default backend that answers model not found for every name. The tell is in the table above — when *every* model fails, stop editing model names. Print the outgoing URL and read it, rather than trusting what the config file says it should be. Also check for a stale environment variable such as an old base URL exported in your shell profile, which silently wins over the value in your code.
4. "Does not exist or you do not have access" is two errors in one sentence
Many providers return the same message whether a model is unknown or merely off-limits to you, so the wording alone cannot tell you which. Separate them yourself: if the model appears in the provider's public documentation but not in the list your key returns, check both naming and access; the list may not expose every supported route. Typical reasons are that the key belongs to a different project or organisation than the one with access, the model is limited to certain account levels, or it is still rolling out. Confirm by listing models with a key you know has access. Website access is a separate entitlement from API access, so being able to chat with a model in a browser proves nothing about your key. Where the provider documents access rules, follow its official page for the current requirements rather than a forum post.
5. Listed, but still 404: you are calling the wrong route
This one surprises people because the first check passes. A model can be registered on an endpoint yet be served on only some of its routes — chat completions but not a newer responses-style route, text generation but not embeddings, or a chat model sent to an image route. Some gateways also answer with a not-found style error when the model exists but does not support a feature in the request. Look at which path your SDK version actually calls, because upgrading a library can quietly switch routes. Then repeat the same model on the plain chat completions route with a minimal body: if that works, the model is fine and the route or feature is the problem.
6. It worked yesterday: diff the request, not your memory
Sudden failures with no code change usually come from something that moved underneath you. An alias that tracked the newest version may now point at a different build, a dated snapshot may have been removed, an IDE or CLI update may have changed its default model, or a rotated key may belong to a different project. Keep one known-good request — URL, headers without the secret, and body — in your repo. When something breaks, run both and compare field by field. If the vendor really retired the model, its release notes will say so, and the fix is a different model; on an OpenAI-compatible endpoint that is one string in configuration, not a re-integration.
7. One-character differences and tools that rewrite names
Model strings are compared exactly. The usual culprits: a dot where the provider uses a hyphen (`4.5` versus `4-5`), a missing or extra date suffix, uppercase letters, a trailing space or invisible character copied from a document, and a display name such as 'Claude Sonnet' used where the API wants an identifier. Then there are tools in the middle. Gateways, SDK wrappers and IDE plugins sometimes add or strip a provider prefix before a slash, map names through their own table, or fall back to a default model when the field is empty. If the same string works in a bare curl call but fails inside a tool, the tool is transforming it. The same pattern explains local runners such as Ollama and front-ends such as Open WebUI, where the error often means the model was never pulled or the front-end points at a different server from the one you tested.
8. Switching providers? Names do not travel, so check them at startup
When you change base_url to a different provider or gateway, keep in mind that each one has its own naming. The vendor's official name may work, a gateway's own code may work, or only one of the two. cocodot accepts both: official names and codes (such as `mcs-6` for Claude Sonnet 5) route to the same model, the full list is at cocodot.co/pricing#models, and it is machine-readable at `GET https://cocodot.co/api/ai/models`. Whichever provider you use, make the check automatic: read the model name from configuration, call the list endpoint once at startup, and refuse to start with a clear message if the name is absent. A deployment that fails fast on boot is far easier to fix than one that fails on the first real user request with a vague 404.
Symptom → likely cause → how to confirm
| Symptom | Likely cause | How to confirm |
|---|---|---|
| Other model names work, this one fails | Name, suffix or case is wrong | Copy the ID from /v1/models and diff it against what you send |
| Every model name fails | base_url or path is wrong | Print the full outgoing URL; look for a missing or doubled /v1 |
| Name is in the docs but not in your list | Key or project has no access | List models with this key, then with a key that works |
| Name is in your list but calls still 404 | Wrong API route for that model | Check which path your SDK calls and which routes the model supports |
| Works in curl, fails in your app | Tool rewrites or overrides the name | Log the request body the tool really sends |
| Worked yesterday, fails today | Alias moved, config changed, key swapped | Diff today's request against a saved working one |