Repository navigation
[Bug]: OpenCode model missing at startup, shows Unavailable until manual provider refresh #15994
Description
What happened
At startup the saved model opencode/muse-spark-1.3-contributor-free shows in the model picker with an Unavailable badge. After Settings, Providers, Refresh providers, the same slug resolves to Muse Spark 1.3 Free with no badge.
Steps to reproduce
- Set model to
opencode/muse-spark-1.3-contributor-free. - Close T3 Code completely.
- Open T3 Code again.
- Open model picker. The saved model shows as
opencode/muse-spark-1.3-contributor-freewith anUnavailablebadge. - Go to Settings, Providers, run Refresh providers.
- Open model picker again. The same slug now resolves to
Muse Spark 1.3 Freewith no badge.
Expected behavior
Startup catalog should include the same OpenCode models as manual refresh, or the UI should show a loading state instead of Unavailable while the first probe is still running.
Actual behavior
At startup the saved model is kept as a row with isUnavailable:true. After manual refresh it resolves normally. Screenshot attached.
Impact
Minor bug or occasional failure
Version or commit
main @ cf3e714b0f58e29c8fa8660db50d2187e3263b65 (2026-10-05). Desktop app is T3 Code Nightly.
Environment
Windows, T3 Code Nightly, OpenCode driver 2.0.22, provider opencode.
Diagnosis, from code read
apps/web/src/modelSelection.ts:93-112appends theUnavailablerow when the savedopencodeslug is absent from raw models.apps/web/src/components/chat/ModelListRow.tsx:80-84renders the badge.- Startup returns a pending OpenCode snapshot with
models=[], inapps/server/src/provider/Layers/OpenCodeProvider.ts:336-379. The realcheckProviderruns forked in background with errors ignored, inapps/server/src/provider/makeManagedServerProvider.ts:281-284. - Boot hydrates UI from per instance disk cache, in
apps/server/src/provider/Layers/ProviderRegistry.ts:351-425. A cache written before the new model existed misses the slug. - OpenCode 2 loads its catalog lazily and retries empty
model.listfor up to 5s, inapps/server/src/provider/Layers/OpenCodeProvider.ts:389-411.lastLoadedis memory only, so a restart loses it. Failed or empty probes retain old rows, inProviderRegistry.ts:118-191. - Manual refresh in
apps/server/src/ws.ts:2263-2304runsmodelManifest.forceRefresh,invalidateCaches, fresh maintenance, thenproviderRegistry.refresh(). That hits a warm server, lists 465 models, persists new cache inProviderRegistry.ts:448-468.
Likely cause is cold start racing a lazy OpenCode 2 catalog plus stale disk cache, not a filter. No free versus paid filtering exists in the OpenCode path.
What I checked locally:
orchestrator_capabilities now: opencode has 465 models, includes muse-spark-1.3-contributor-free
provider status cache after refresh lists 465 models and contains
slug "opencode/muse-spark-1.3-contributor-free"
name "Muse Spark 1.3 Free"
Server trace holds spans only. No muse-spark or refreshProviders strings found there.
Workaround
Run Settings, Providers, Refresh providers once after startup.
Activity
juliusmarminge commentedon Oct 5, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks for the careful code read and the local checks, @ignaciorasetti. Your diagnosis holds up on current
main(cf3e714b0f). This looks like a startup catalog race, not a free-vs-paid filter.What I found
appendUnavailableDynamicModelSelectioninapps/web/src/modelSelection.tsadds the saved slug withisUnavailable: truewhenever it's missing from the OpenCode instance's model list, andModelListRowrenders the badge. The server never sends that flag.ProviderRegistryLivehydrates from the per-instance cache. The live snapshot starts asmakePendingOpenCodeProvider(installed: false,status: "warning", no models), and the realcheckProvideris forked with its failure ignored (makeManagedServerProvider.ts).OpenCodeDriver.tssetsrefreshOnInterval: falseandcheckProviderOnSettingsChange: () => false.makeOpenCode2ModelLoaderretries an emptymodel.listfor up to 5s, then keeps the first non-empty list, andlastLoadedlives only in memory. Manual refresh (serverRefreshProviderswithrefreshModels: true) hits an already-warm OpenCode 2 server, which is why the slug then resolves to Muse Spark 1.3 Free.shouldRetainMissingProviderModelskeeps them only for the pending boot snapshot and for a failed probe (status: "error"). A completed warning with an empty list, or a ready probe with a partial list, replaces the cache. Since nothing schedules another check, a partial first list sticks.A useful next check: after one manual refresh, cold-start again. If the badge comes back, the startup probe is overwriting a good cache with a partial list. If it stays resolved until OpenCode adds another model, the disk cache was just stale and the boot probe never replaced it.
Related open PRs, neither merged: #15202 waits for
integration.list(plugin activation) before trustingmodel.list, which is closer if this model only appears after theopencodeprovider activates. #15510 waits formodel.updatedand mainly addresses display names, so it probably wouldn't explain a missing slug.Workaround: as you noted, run Refresh providers once after startup.
Likely fix area
makeOpenCode2ModelLoaderinapps/server/src/provider/Layers/OpenCodeProvider.ts. One option is to wait for the catalog to settle (as fix(opencode): wait for provider activation before caching models #15202 does) before treating a list as complete.OpenCodeDriver.ts/ProviderRegistry.ts. Another option is to schedule a follow-up probe after boot, or to avoid replacing a cached list with a partial one.apps/web/src/modelSelection.ts. A third option is to show a loading state rather than Unavailable while the first probe is still pending.A maintainer will decide on the fix direction.
ignaciorasetti commentedon Oct 5, 2026
Follow-up on the next check you suggested.
I checked that if I refresh and cold start again, the \Unavailable\ badge on \opencode/muse-spark-1.3-contributor-free\ comes back. So this is not a one time stale cache. Every startup reproduces it.
One more detail: on my last start I had to run Refresh providers twice in a row before the slug resolved. The first refresh did not bring it back.
Narayan201120 commentedon Oct 12, 2026
@juliusmarminge this still reproduces on my machine, on nightly, so I do not think the race is behind us.
What I am seeing at startup, from the thread details panel banner:
and the composer model picker shows the saved model with an
Unavailablebadge. Same shape as the original report: the server is up, the catalog is empty, and the slug only resolves after a manual refresh. One difference from the original report is that mine is anopencode-go/*slug (opencode-go/glm-5.3) rather thanopencode/muse-spark-1.3-contributor-free, so this looks like it is not limited to theopencodeprovider prefix or to a free tier.Still on OpenCode 2, Windows, nightly. I have not isolated whether the banner and the badge are the same empty-list read or two different ones, the banner coming from the provider status check and the badge from the model catalog.
I do not have the log handles to say whether
makeOpenCode2ModelLoaderis still keeping an empty first list after its retry window, or whether this is the stale disk cache hydrating the UI before the probe lands. @ignaciorasetti had to refresh twice in a row on one start, which also fits either.Screenshot to follow.
No code from me on this one yet.
razzeee commentedon Oct 16, 2026
I also have this from time to time and I just had a colleague that ran into it.
Narayan201120 commentedon Oct 16, 2026
try refreshing from providers section in the settings. works for me. else restart the app
shunkakinoki commentedon Oct 20, 2026
Same symptom on
0.1.1-nightly.20261019.3360with OpenCode2.0.32on Linux, as the "Limited" warning: "OpenCode 2 is running, but it did not list any models yet."Cause found in
provider-opencode:makeOpenCode2ModelLoaderrepeatsmodel.listuntil it gets a non-empty list, withtimeoutOption("5 seconds"). That five seconds runs insideopenCode2Server.withConnection, so it includes spawning and verifying a coldopencode serve. The server is closed again afterOPENCODE_SERVER_IDLE_TTL(30s), so most health checks start cold./api/modelwith{"code":"service_starting"}and lists models about 2.3s after spawn on an idle host. Measured on the server T3 spawned itself. A loaded host goes past 5s.lastLoaded, which is[]for a new instance.checkOpenCode2then reportswarningwith zero models, and that stays until the nextproviderHealthRefreshInterval(5 min onbalanced). A manualserver.refreshProvidersreturnsreadywith 531 models.Possible fixes: start the 5s budget after the server is verified, keep the previous snapshot's models instead of replacing them with
[], or keep the server warm between health checks.beci commentedon Oct 20, 2026
Same issue on Windows, adding a data point from the server trace.
T3 Code Nightly
0.1.1-nightly.20261020.3399, OpenCode2.0.32, Windows 11, managed server (noserverUrl). It happens on the first launch after a reboot or app update.checkOpenCode2spans fromserver.trace.ndjson, all on the same day:startServerAttemptGET /api/modelcheckOpenCode2In the failing run, the spawn used about 2 s of the 5 s budget. The first
/api/modelread was still running when the timeout interrupted it. After that, nocheckOpenCode2ran again until the next app restart about 2.5 hours later, even though severalws.rpc.server.refreshProviderscalls ran in between. Taking the server spawn out of the timed region, as discussed above, would have prevented both the failure and the near miss.t3dotgg commentedon Oct 21, 2026
Note
🤖 Claude Opus 5.5 responding on behalf of Theo
Thanks for the report. One part of this is fixed on main in #16448. Please test on the nightly built from main on 2026-10-21, or on the next stable release. One part is still open: A cold catalog that stays empty through the five-second limit can still omit the saved model. If that part still matters to you, please open a new issue for that part only.
mynameistito commentedon Oct 21, 2026
Another reproduction of the empty OpenCode 2 startup catalog:
What happened
On every T3 Code startup, OpenCode 2 is reported as running but with no models listed. Refreshing provider status (or toggling the OpenCode provider off and on) makes the models appear.
Diagnosis and evidence
The local
server.trace.ndjsonmatches the cold-start timeout described in this issue. In the failingcheckOpenCode2run, starting the managed OpenCode server took about 3.46 seconds. The subsequentGET /api/modelwas interrupted after about 1.57 seconds, and the provider check completed at about the five-second limit without models. A later provider refresh successfully loaded the catalog.This appears to be the remaining empty-catalog-through-timeout case noted in the Oct 21 triage comment. The catalog-settling fix in #16448 addresses an early partial nonempty result; this trace instead shows the model request still in flight when the five-second check is interrupted.
Reproduction
Environment
0.1.2-nightly.20261021.348610.0.26300v26.8.20.1.1(launched withbunx t3 triage; this is not the desktop app version)Related work
PR #16448 merged on Oct 19 and settles model catalogs before caching. The Oct 21 triage note on this issue says a cold catalog that remains empty through the five-second limit may still omit models.
Evidence summarized from local server trace; user home path and credentials omitted.
Prepared by Codex, GPT-6, via T3 Code triage.
t3dotgg commentedon Oct 22, 2026
Note
🤖 Claude Opus 5.5 responding on behalf of Theo
Reopening: a second user still sees the empty OpenCode model list at startup on nightly 0.1.2-nightly.20261021.3486, which includes #16448. The 5-second startup check can end before the model list has loaded.