You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
createOpencodeServer({config}) / OPENCODE_CONFIG_CONTENT is invisible to the v2 API surface (ModelUnavailableError for custom providers) #36748
A custom provider using npm: "@ai-sdk/anthropic" (an Anthropic Messages-API-compatible endpoint) fails at model-resolve time with ModelUnavailableError, even though the provider and its model show up in GET /config/providers (including under default). This blocks routing to the custom provider entirely; with no explicit model, opencode silently falls back to its built-in OpenCode Zen model instead.
Environment
opencode 1.17.18 (also reproduced on 1.17.16, installed in isolation — both fail identically, so not a recent regression)
macOS (arm64), Bun
Reproduces on a bare bun init project, so it is not app-specific.
Config (matches the documented custom-provider schema)
ERROR message="Failed to drain Session" cause="SessionRunnerModel.ModelUnavailableError: Model unavailable: myproxy/claude-haiku-4-5-20251001
at SessionRunnerModel.resolve ..."
The endpoint does not need to be reachable — resolve() throws before any network call, so this repros with nothing running on :18080.
What I ruled out
opencode version — 1.17.16 and 1.17.18 both fail.
Config shape — matches the custom-provider docs (npm + name + options.baseURL + models[].name).
models.dev reachability — reachable (HTTP 200) when tested; still fails.
Model metadata — adding limit/cost/capabilities to the model entry doesn't help.
Package availability — on my machine @ai-sdk/anthropic was absent system-wide and opencode did not auto-install it; installing it in the process's cwd node_modulesand via bun add -g both left resolve() failing.
Questions
Is opencode expected to auto-install a custom provider's npm package? If so, where, and is there a way to see/trigger that install (it never produced any @ai-sdk/anthropic on disk here)?
If the package must be provided by the user, where does opencode's compiled binary resolve custom-provider packages from? (cwd node_modules and bun global both seem ignored.)
Happy to provide more logs. This may be partly environment-specific on my side, but the "provider listed in /config/providers yet ModelUnavailable at resolve" behavior seems worth clarifying regardless.
This issue might be a duplicate of existing issues. Please check:
Provider-level npm field silently ignored unless models is also configured #33888: Provider-level npm field silently ignored unless models is also configured — describes the same root cause where custom npm package resolution doesn't apply to all models, which may explain why the provider appears in /config/providers but fails at resolve() time.
In particular, #33888 documents that provider.npm is only consulted inside the loop over explicitly listed provider.models entries, which may interact with how the resolver locates the installed package on disk. Your question about where opencode resolves custom provider packages from is directly relevant to that issue.
The v2 session runner never loads provider npm packages.packages/core/src/session/runner/model.ts (fromCatalogModel / supported) ships built-in protocol implementations (@opencode-ai/llm: AnthropicMessages / OpenAIResponses / OpenAICompatibleChat) and selects one by the string value of the catalog model's api.package. On the v2 path, npm: "@ai-sdk/anthropic" is only ever compared as a string — installing the package (cwd node_modules, bun add -g, anywhere) cannot matter, which is why all the placement experiments in this report failed.
ModelUnavailableError just means "model not in the v2 catalog", and the v2 Config service (packages/core/src/config.ts) loads config files only — opencode.json/.jsonc discovered from the location directory up to the project root, plus the global config dir. It never reads OPENCODE_CONFIG_CONTENT, which is the only thing the SDK's createOpencodeServer({ config }) sets (packages/sdk/js/src/v2/server.ts). Config passed through the SDK is therefore invisible to the entire v2 API surface — while v1 endpoints like /config/providers, whose loader does read OPENCODE_CONFIG_CONTENT (packages/opencode/src/config/config.ts), happily report the provider. That split is exactly the confusing symptom in the original report.
Confirmed empirically on 1.17.18 (identical v1-shape provider config in each case; mock Anthropic Messages endpoint on 127.0.0.1):
Where the provider config lives
GET /api/provider (v2 catalog)
prompt
createOpencodeServer({ config })
absent
ModelUnavailableError
opencode.json in the served dir (git repo)
present — migrated to api: {type:"aisdk", package:"@ai-sdk/anthropic", url}
works, emits POST /v1/messages
opencode.json in a non-git dir
absent
—
dir pointed to by OPENCODE_CONFIG_DIR
absent
—
Actionable items hiding in this report, stated precisely:
SDK/server contract gap (the headline):createOpencodeServer({ config }) silently does nothing for the v2 API surface. Either the v2 Config service should ingest OPENCODE_CONFIG_CONTENT, or the SDK option should be documented as v1-only.
Config discovery requires the served directory to be inside a git project; the same file in a non-git directory is silently ignored.
OPENCODE_CONFIG_DIR is honored by the v1 loader only, not the v2 catalog.
Workaround for anyone landing here: put the provider block in an opencode.json inside a git repo and run the server from there — works on both 1.17.16 and 1.17.18. (This also disproves the earlier "environment / on-demand install" hypothesis in the thread: which behavior you get depends on which API surface the client drives — v1 reads the SDK-passed config, v2 doesn't — not on the machine.)
changed the title [-]Custom @ai-sdk/anthropic provider: ModelUnavailableError at resolve despite provider listed in /config/providers[/-][+]createOpencodeServer({config}) / OPENCODE_CONFIG_CONTENT is invisible to the v2 API surface (ModelUnavailableError for custom providers)[/+]on Jul 14, 2026
Activity
github-actions commentedon Jul 13, 2026
This issue might be a duplicate of existing issues. Please check:
npmfield silently ignored unlessmodelsis also configured #33888: Provider-levelnpmfield silently ignored unlessmodelsis also configured — describes the same root cause where customnpmpackage resolution doesn't apply to all models, which may explain why the provider appears in/config/providersbut fails atresolve()time.@ai-sdk/anthropicprovider drops API key at runtime — same provider type and config shape, different failure symptom (401 vsModelUnavailableError), but the underlying npm package resolution path is shared.In particular, #33888 documents that
provider.npmis only consulted inside the loop over explicitly listedprovider.modelsentries, which may interact with how the resolver locates the installed package on disk. Your question about where opencode resolves custom provider packages from is directly relevant to that issue.doryokujin commentedon Jul 14, 2026
Update — root cause found. It is not npm package resolution; this issue's original framing (and title) was wrong. Retitling accordingly.
Source-diving
v1.17.18explains everything observed above:The v2 session runner never loads provider npm packages.
packages/core/src/session/runner/model.ts(fromCatalogModel/supported) ships built-in protocol implementations (@opencode-ai/llm: AnthropicMessages / OpenAIResponses / OpenAICompatibleChat) and selects one by the string value of the catalog model'sapi.package. On the v2 path,npm: "@ai-sdk/anthropic"is only ever compared as a string — installing the package (cwdnode_modules,bun add -g, anywhere) cannot matter, which is why all the placement experiments in this report failed.ModelUnavailableErrorjust means "model not in the v2 catalog", and the v2 Config service (packages/core/src/config.ts) loads config files only —opencode.json/.jsoncdiscovered from the location directory up to the project root, plus the global config dir. It never readsOPENCODE_CONFIG_CONTENT, which is the only thing the SDK'screateOpencodeServer({ config })sets (packages/sdk/js/src/v2/server.ts). Config passed through the SDK is therefore invisible to the entire v2 API surface — while v1 endpoints like/config/providers, whose loader does readOPENCODE_CONFIG_CONTENT(packages/opencode/src/config/config.ts), happily report the provider. That split is exactly the confusing symptom in the original report.Confirmed empirically on 1.17.18 (identical v1-shape provider config in each case; mock Anthropic Messages endpoint on 127.0.0.1):
GET /api/provider(v2 catalog)createOpencodeServer({ config })ModelUnavailableErroropencode.jsonin the served dir (git repo)api: {type:"aisdk", package:"@ai-sdk/anthropic", url}POST /v1/messagesopencode.jsonin a non-git dirOPENCODE_CONFIG_DIRActionable items hiding in this report, stated precisely:
createOpencodeServer({ config })silently does nothing for the v2 API surface. Either the v2 Config service should ingestOPENCODE_CONFIG_CONTENT, or the SDK option should be documented as v1-only.OPENCODE_CONFIG_DIRis honored by the v1 loader only, not the v2 catalog.Workaround for anyone landing here: put the provider block in an
opencode.jsoninside a git repo and run the server from there — works on both 1.17.16 and 1.17.18. (This also disproves the earlier "environment / on-demand install" hypothesis in the thread: which behavior you get depends on which API surface the client drives — v1 reads the SDK-passed config, v2 doesn't — not on the machine.)[-]Custom @ai-sdk/anthropic provider: ModelUnavailableError at resolve despite provider listed in /config/providers[/-][+]createOpencodeServer({config}) / OPENCODE_CONFIG_CONTENT is invisible to the v2 API surface (ModelUnavailableError for custom providers)[/+]github-actions commentedon Sep 13, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.