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
v2: config-declared custom-provider models silently become 0 in catalog when models.opencode.ai fetch fails at boot (provider survives, resolution-by-ID still works) #41360
Custom providers declared entirely in config (provider. with an inline models map, using model IDs not in the public models.opencode.ai catalog) end up with 0 models and disappear from the picker — with no error shown. The provider entry survives; only its models are dropped.
Cause: the boot fetch of https://models.opencode.ai/api.json is swallowed on failure (logError "Failed to fetch models.dev" then Effect.ignore), and custom-model hydration then produces an empty models map instead of keeping the config-declared models. The empty catalog persists until the server rebuilds during a successful fetch.
Model resolution by explicit ID keeps working the whole time (run -m / succeeds), so only the catalog/listing path breaks, not resolution. Typing the model name into the picker search box returns nothing, confirming the catalog is genuinely empty rather than filtered.
Related but not duplicate: #35090, #35713, #32986, #34730 describe loud errors/crashes from the models.dev fetch; this is silent, persistent loss of config-declared custom models while the app looks healthy.
Expected: config-declared models should register and list regardless of the models.opencode.ai fetch; a failed fetch should degrade gracefully (warn + keep declared models), not zero them out.
Plugins
none required to reproduce (also repro'd with plugins disabled)
Result: picker empty; model name absent even when typed in search; GET /api/model -> {"data":[]}; GET /api/provider shows the provider with 0 models; no UI error; persists across relaunches until the catalog rebuilds during a good fetch.
Verified: same config + reachable fetch + fresh server start -> full catalog lists all declared models.
Screenshot and/or share link
No response
Operating System
macOS 26.6.1 (arm64)
Terminal
OpenCode Beta desktop app (also repro'd via opencode2 CLI)
I think a good part of what is reported here is a startup race rather than a config parsing problem: serve starts answering requests before the catalog is hydrated, so what you get back depends entirely on how soon after startup you ask.
Repro on 2.0.6 (macOS arm64), with six providers declared in ~/.config/opencode/opencode.jsonc:
t+0.03s (connection refused)
t+1.25s providers=0 models=70
t+2.53s providers=6 models=138
t+3.64s providers=6 models=138
... stable from here on
Two things stand out:
The window is real but short. Before roughly 2.5s the catalog is empty or partial; after that it is complete and stays that way. Nothing about the config changes in between, so a client that asks once at the wrong moment concludes the providers do not exist.
The endpoints disagree during that window. At t+1.25s /api/provider returns zero entries while /api/model already returns 70. Anything that guards on "no providers, so bail out" gives up even though the model list is populated.
There is also a staged fill: the built-in provider lands about a second before the ones declared in config, so an early read can produce a catalog that looks valid but silently omits every user-declared provider. That is the failure mode I would worry about most, because it does not raise an error anywhere.
The CLI is not affected, which I think is why this looks like an API-only bug: opencode models resolves through Provider.Service.list() in-process and waits for hydration, while the HTTP handler reads Catalog.Service state as it stands at request time.
For anyone hitting this from a client: the server listening on ... line and /api/info both become available before the catalog does, so neither is usable as a readiness signal today. Polling until the contents stop changing works, but an explicit signal (or having the list endpoints await hydration) would obviously be nicer.
Happy to test a patch against this setup if that helps.
Activity
benjaminfrombe commentedon Sep 17, 2026
I think a good part of what is reported here is a startup race rather than a config parsing problem:
servestarts answering requests before the catalog is hydrated, so what you get back depends entirely on how soon after startup you ask.Repro on 2.0.6 (macOS arm64), with six providers declared in
~/.config/opencode/opencode.jsonc:Two things stand out:
The window is real but short. Before roughly 2.5s the catalog is empty or partial; after that it is complete and stays that way. Nothing about the config changes in between, so a client that asks once at the wrong moment concludes the providers do not exist.
The endpoints disagree during that window. At t+1.25s
/api/providerreturns zero entries while/api/modelalready returns 70. Anything that guards on "no providers, so bail out" gives up even though the model list is populated.There is also a staged fill: the built-in provider lands about a second before the ones declared in config, so an early read can produce a catalog that looks valid but silently omits every user-declared provider. That is the failure mode I would worry about most, because it does not raise an error anywhere.
The CLI is not affected, which I think is why this looks like an API-only bug:
opencode modelsresolves throughProvider.Service.list()in-process and waits for hydration, while the HTTP handler readsCatalog.Servicestate as it stands at request time.For anyone hitting this from a client: the
server listening on ...line and/api/infoboth become available before the catalog does, so neither is usable as a readiness signal today. Polling until the contents stop changing works, but an explicit signal (or having the list endpoints await hydration) would obviously be nicer.Happy to test a patch against this setup if that helps.