OpenCode Model Not Found: Fix Provider, Model ID, and API Configuration Errors

Fix OpenCode model not found errors by separating provider IDs from model IDs, checking Base URL paths, validating API keys, and debugging 401, 404, and custom-provider configuration issues.

O
OurToken Team//13 min
OpenCode Model Not Found: Fix Provider, Model ID, and API Configuration Errors

The opencode model not found error usually means OpenCode is sending a valid-looking request with the wrong model identity. The problem is rarely that the model disappeared. More often, the provider name, model ID, Base URL, or configuration file is being interpreted differently by OpenCode and the API gateway. A display name such as “GPT-5.6 Terra” is not necessarily the model ID, and a provider ID such as ourtoken is not the same thing as gpt-5.6-terra.

This guide shows how to diagnose the failure without guessing. You will learn how OpenCode constructs a full model ID, how to verify model names from /v1/models, why /v1 belongs in baseURL but /chat/completions does not, and how to distinguish a 401 Unauthorized from a 404 or model_not_found response. The examples use an OpenAI-compatible custom provider, including an OurToken configuration, but the debugging method applies to any OpenCode provider.

Verification note: OpenCode provider, model, and configuration behavior was checked against the official OpenCode documentation on 2026-08-31. OurToken endpoint details were checked against the current OpenCode Custom Provider guide. Model availability and pricing can change, so verify the live catalog before copying an ID into a project.

OpenCode Model Not Found: The Fastest Diagnosis

Run these checks in order. They isolate the failure before you spend time changing prompts or reinstalling OpenCode:

  1. Confirm the provider ID in the model selector or opencode.json.
  2. Confirm the exact model ID from the provider's model catalog.
  3. Confirm that baseURL is the API root, normally ending in /v1.
  4. Confirm that the API key is present and has permission to call the route.
  5. Test the gateway directly with /v1/models or a short completion request.
  6. Reload OpenCode after changing the configuration.

For an OurToken custom provider, the expected values look like this:

Provider ID: ourtoken
Base URL:    https://api.ourtoken.ai/v1
Model ID:    gpt-5.6-terra
Full model:  ourtoken/gpt-5.6-terra

The full model is the value OpenCode uses internally. The provider ID is the namespace from the provider object. The model ID is the key under that provider's models object. The gateway receives the model ID, not the combined ourtoken/gpt-5.6-terra string.

Why OpenCode Says Model Not Found

OpenCode uses the AI SDK and Models.dev to support many hosted and local providers. Its model configuration follows a simple hierarchy:

OpenCode model selection
        |
        v
provider_id/model_id
        |
        +--> provider configuration
        |       +--> baseURL
        |       +--> apiKey
        |       +--> models map
        |
        v
API request with the model_id

The slash is not cosmetic. If your provider ID is ourtoken and the model key is deepseek-v4-flash, OpenCode expects ourtoken/deepseek-v4-flash as the full selection. If you write only deepseek-v4-flash, OpenCode may look for that model under a different provider. If you write openai/deepseek-v4-flash, the gateway may receive the wrong model because the openai namespace points to a different configuration.

Provider ID, Display Name, and Model ID

These three values have different jobs:

ValueExampleWhere It Is Used
Provider IDourtokenKey under provider and first part of full model
Display nameOurTokenLabel shown in OpenCode's provider or model picker
Model IDgpt-5.6-terraKey under provider.ourtoken.models and API request body

Only the model ID needs to match the gateway's route exactly. Capitalization, punctuation, and version suffixes matter. GPT-5.6 Terra, gpt-5.6-terra, and gpt-5.6 are different strings even if a UI makes them look related.

OpenCode's official model documentation describes the full ID as provider_id/model_id. For a custom provider, the provider ID is the key from your configuration and the model ID is the key from provider.models. That is the first thing to inspect when the error says the model cannot be found.

Verify the Model ID Before Editing OpenCode

Do not start by changing the model string repeatedly. Ask the API what it supports. For an OpenAI-compatible endpoint, call the models route directly:

curl https://api.ourtoken.ai/v1/models -H "Authorization: Bearer $OURTOKEN_API_KEY"

Use an API key from your local environment; never paste a production secret into a shell history that is shared with other users. The response should contain model objects with IDs. Copy the id value exactly, not the human-readable name value.

The current OurToken model catalog is also useful for checking supported routes, but the API response is the final authority for what your key can access at runtime. A model can be listed in a general catalog and still be unavailable to a particular account, region, balance, or provider route.

Test One Model With a Raw Request

Once you have an ID, test it outside OpenCode. This separates API authentication and routing from the local agent configuration:

curl https://api.ourtoken.ai/v1/chat/completions -H "Authorization: Bearer $OURTOKEN_API_KEY" -H "Content-Type: application/json" -d '{"model":"gpt-5.6-terra","messages":[{"role":"user","content":"Reply with the word OK."}]}'

If this request fails, fix the provider or account before touching OpenCode. If it succeeds, the remaining problem is usually the OpenCode config path, provider package, model map, or stale process state.

Base URL Errors: The Most Common 404 Cause

OpenCode and the OpenAI-compatible provider package append the operation path automatically. Your baseURL should point to the API root, not to a specific operation. For OurToken, use:

https://api.ourtoken.ai/v1

Do not use these values as baseURL:

https://api.ourtoken.ai
https://api.ourtoken.ai/v1/chat/completions
https://api.ourtoken.ai/v1/responses
https://api.ourtoken.ai/v1/models

The first may omit the version prefix expected by the gateway. The other three hard-code an operation path that OpenCode will append again, producing a malformed URL such as /v1/chat/completions/chat/completions. Depending on the gateway, that becomes a 404, an unsupported-route error, or a misleading model error.

The OurToken guide states the same rule: use https://api.ourtoken.ai/v1 exactly and do not append /responses or another API path. The existing OpenCode Custom Provider article shows the same request path: OpenCode agent → provider → @ai-sdk/openai-compatible → Base URL → /chat/completions → selected model.

Trailing Slashes and Version Prefixes

Keep the URL format consistent with the provider documentation. A trailing slash is usually normalized by HTTP clients, but a duplicated version prefix is not. If a provider expects /v1, putting /v1/v1 in the configuration can look like a model failure because the request never reaches model routing.

A quick way to spot this is to enable request logging in your development environment or inspect the gateway access log. You want to see one version prefix and one operation path:

POST /v1/chat/completions

Not POST /v1/v1/chat/completions or POST /v1/chat/completions/chat/completions.

A Known-Good Custom Provider Configuration

Create opencode.json in the project root for a project-specific provider. The following example uses environment-variable secret resolution and three model IDs from the OurToken guide:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "ourtoken": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "OurToken",
      "options": {
        "baseURL": "https://api.ourtoken.ai/v1",
        "apiKey": "{env:OURTOKEN_API_KEY}"
      },
      "models": {
        "gpt-5.6-terra": {"name": "GPT-5.6 Terra"},
        "deepseek-v4-flash": {"name": "DeepSeek V4 Flash"},
        "glm-5.2": {"name": "GLM 5.2"}
      }
    }
  },
  "model": "ourtoken/gpt-5.6-terra"
}

Set the secret before launching OpenCode. On PowerShell:

$env:OURTOKEN_API_KEY = "your-key-from-ourtoken"
opencode

The model aliases in the example are display labels only. The keys are the values sent to the gateway. If /v1/models returns a different ID, replace the key and the default model value with the returned ID.

OpenCode supports JSON and JSONC formats. It also merges configuration files rather than replacing them. A project config has higher precedence than the global config at ~/.config/opencode/opencode.json. That means an old project-level model setting can override a corrected global provider, which is why checking the nearest project file is important.

Credentials Stored by /connect

For providers configured through OpenCode's /connect command, credentials are stored in ~/.local/share/opencode/auth.json. A key can be valid in that file but still not be used by your custom provider if the provider ID or authentication precedence is different. When debugging, make the source of the key explicit: use the provider's documented environment variable or a {file:...} reference, then remove conflicting credentials from a test configuration.

Never commit a real API key to opencode.json, auth.json, or a project .env file. The configuration schema can be committed when it contains an environment or file reference.

Distinguish 401, 404, and Model Not Found

These errors point to different layers. Treating all of them as “the model is unavailable” wastes time.

ErrorUsually MeansFirst Check
401 UnauthorizedKey missing, malformed, expired, or not sentEnvironment variable, secret reference, Bearer header
403 ForbiddenKey is valid but lacks permission or account accessAccount, route permissions, balance, policy
404 Not FoundURL path or endpoint is wrongBase URL, version prefix, appended operation path
model_not_foundEndpoint works but model ID is unknown or unavailableExact ID from /v1/models, provider model map
Provider missing in pickerConfig not loaded or provider disabledFile path, JSON syntax, provider ID, reload
Model missing in pickerModel not declared or blacklistedprovider.models, whitelist/blacklist, full ID

Fixing 401 Unauthorized

Start outside OpenCode:

if ($env:OURTOKEN_API_KEY) { "Key is present" } else { "Key is missing" }

Do not print the key itself. If the variable is missing, set it in the same terminal session that starts OpenCode, or configure a persistent user variable and start a new shell. Check that the config references {env:OURTOKEN_API_KEY} rather than the literal string OURTOKEN_API_KEY.

If the raw cURL request succeeds but OpenCode returns 401, inspect which provider is selected. You may be calling a built-in openai provider while expecting the ourtoken credentials. The selected full model should begin with the provider ID that owns the key.

Fixing 404

Compare the URL in the raw request with the URL generated by OpenCode. For an OpenAI-compatible chat route, it should be one /v1 prefix followed by /chat/completions. Remove operation paths from baseURL, and do not assume that a Responses API path is interchangeable with a Chat Completions path.

Fixing model_not_found

A model_not_found response means the request reached a model-aware endpoint. Check the model field in the actual request, not just the label shown in the UI. For a custom provider, the request should contain gpt-5.6-terra, not OurToken/gpt-5.6-terra and not GPT-5.6 Terra.

Configuration Precedence and Stale State

OpenCode can load remote, global, project, and custom configuration files. Later configuration values override earlier values when the same key conflicts, while unrelated settings are merged. This is convenient until a stale project file keeps selecting a deleted model.

Use this checklist when the file looks correct but the error remains:

  1. Search the repository for every opencode.json and opencode.jsonc.
  2. Check the nearest Git root; OpenCode searches the current directory and traverses toward that root.
  3. Inspect the global file at ~/.config/opencode/opencode.json.
  4. Check whether OPENCODE_CONFIG points to a custom file.
  5. Remove duplicate model keys and choose one default.
  6. Restart OpenCode or reload the project configuration after editing.

The model picker can also hide entries. OpenCode supports provider blacklist and whitelist settings. A model may be correctly declared but filtered from /models. Temporarily remove those filters while diagnosing, then add back only the routes your team approves.

Testing Multiple Models and Fallbacks

Once one route works, add models incrementally. Do not paste ten IDs into a new configuration and debug all of them at once. Start with one known-good model, verify a short prompt, then add a second model from the same provider.

{
  "provider": {
    "ourtoken": {
      "npm": "@ai-sdk/openai-compatible",
      "options": {
        "baseURL": "https://api.ourtoken.ai/v1",
        "apiKey": "{env:OURTOKEN_API_KEY}"
      },
      "models": {
        "gpt-5.6-terra": {"name": "GPT-5.6 Terra"},
        "deepseek-v4-flash": {"name": "DeepSeek V4 Flash"},
        "glm-5.2": {"name": "GLM 5.2"}
      }
    }
  }
}

OpenCode's model selection and variants are not the same as an application-level fallback policy. A model variant can change options for one model; a fallback policy decides what happens when a request fails. If you need automatic retries across providers, implement that policy at your gateway or application layer and make the behavior observable.

Our LLM model routing guide covers the broader pattern: send routine work to a lower-cost route, reserve stronger models for complex tasks, and keep an approved fallback for provider incidents. For OpenCode itself, the first goal is simpler: prove every configured model ID works independently before adding fallback behavior.

A Repeatable Troubleshooting Runbook

Use this runbook whenever a teammate reports opencode model not found:

Phase 1: Identify the Layer

  • Does the provider appear in OpenCode? If not, inspect config loading and JSON syntax.
  • Does the model appear under /models? If not, inspect the models map and filters.
  • Does a raw /v1/models request return the ID? If not, inspect endpoint and credentials.
  • Does a raw completion work with that ID? If not, inspect account access or route support.

Phase 2: Normalize Values

Write down four values on separate lines:

provider_id = ourtoken
display_name = OurToken
model_id = gpt-5.6-terra
base_url = https://api.ourtoken.ai/v1

Compare each value with the configuration and the network request. This avoids the common mistake of fixing a display name while leaving the model key unchanged.

Phase 3: Prove the Smallest Request

Use /v1/models, then a one-sentence completion, then a short repository task. A large agent prompt can trigger context, tool, or timeout errors that obscure a basic model-routing problem. Keep the first test deliberately boring.

Phase 4: Record the Working Route

When it works, record the provider ID, model ID, Base URL, config file path, and date of verification in your team onboarding notes. Model catalogs change, and a small record prevents the next person from reverse-engineering a working setup.

Common Misconfigurations at a Glance

SymptomLikely Configuration MistakeFix
Provider does not appearInvalid JSON or wrong config locationValidate file and place it at project root
Provider appears but no modelsEmpty models map or filterAdd exact model keys; remove blacklist/whitelist temporarily
Model picker shows a label but request failsDisplay name used as model IDUse the key returned by /v1/models
401 from OpenCode, 200 from cURLWrong provider selected or env var not inheritedSelect full provider/model; launch from the configured shell
404 from every modelOperation path duplicatedSet only the API root in baseURL
One model works, another failsID unavailable for the account or routeVerify each ID independently
Changes have no effectStale process or higher-precedence configReload, restart, and inspect merged config locations

Conclusion

An opencode model not found error is usually a naming or routing mismatch, not a mysterious model outage. Separate the provider ID, display name, and model ID. Use the full provider_id/model_id value when selecting a model in OpenCode, but send only the provider's exact model ID to the API. Confirm that ID with /v1/models before changing anything else.

For an OpenAI-compatible custom provider, keep baseURL at the API root, such as https://api.ourtoken.ai/v1. Let OpenCode append /chat/completions or the operation path. Then test the key and model with a raw request before debugging local configuration.

The reliable order is provider → endpoint → key → model ID → config precedence → reload. Once one route works, add models one at a time and record the verified values. That turns a frustrating setup error into a short, repeatable runbook your whole team can follow.

FAQ

What does opencode model not found mean?

It means OpenCode or the API endpoint cannot resolve the model identifier in the request. The most common causes are a wrong provider namespace, a display name used instead of the model ID, a stale configuration file, or a route that is not available to the selected account.

What is the correct OpenCode model format?

OpenCode uses provider_id/model_id for the full selection. If your provider key is ourtoken and the API model ID is gpt-5.6-terra, select ourtoken/gpt-5.6-terra. The gateway request body should contain only gpt-5.6-terra.

What should baseURL contain for OurToken?

Use https://api.ourtoken.ai/v1. Do not append /chat/completions, /responses, or /models; OpenCode's provider package adds the operation path.

How do I find the correct model ID?

Call https://api.ourtoken.ai/v1/models with a valid Bearer token and copy the id field from the response. You can cross-check the OurToken model catalog, but the live API response is the best runtime check.

Why do I get 401 instead of model not found?

A 401 means authentication failed before model routing. Check that the API key exists in the same shell that launches OpenCode, that the config references the correct environment variable, and that the selected provider is the one holding your key.

Why does cURL work while OpenCode fails?

The raw request may use the correct provider and model while OpenCode loads another config file, selects a different provider, or has a stale process. Compare the exact URL, Authorization header source, model field, and config precedence.

Can I configure multiple models?

Yes. Add each exact model ID under the provider's models map, verify each with a short request, and select it with the provider/model format. Add fallback or routing behavior only after the individual routes work.