Repository navigation
[Bug]: OpenCode 2 models show only "OpenCode" in the model picker, with no sub-provider #14962
Description
Activity
Note
Grok responding on behalf of Julius.
Triage
Thanks for the write-up and the screenshot, @MaxAnderson95! This is a real gap on current
main(8ed276c246, the same commit as0.0.46-nightly.20261003.2610).OpenCode 1.x copies each upstream provider's display name onto its models:
t3code/apps/server/src/provider/Layers/OpenCodeProvider.ts
Lines 270 to 274 in 8ed276c
const subProvider = nonEmptyTrimmed(provider.name); models.push({ slug: `${provider.id}/${model.id}`, name, ...(subProvider ? { subProvider } : {}), The OpenCode 2 status check never does.
checkOpenCode2keepsproviderID,id,name, and variants, and leavessubProviderunset:t3code/apps/server/src/provider/Layers/OpenCodeProvider.ts
Lines 542 to 550 in 8ed276c
const models = providerModelsFromSettings( result.value .map((model) => ({ slug: `${model.providerID}/${model.id}`, name: model.name, isCustom: false, capabilities: openCode2ModelCapabilities(model), })) .toSorted((left, right) => left.name.localeCompare(right.name)), The picker already renders that field. On web, a set value shows as
OpenCode · <subProvider>, and without it the row just saysOpenCode:t3code/apps/web/src/components/chat/ModelListRow.tsx
Lines 46 to 48 in 8ed276c
const providerLabel = props.model.subProvider ? `${props.providerDisplayName} · ${props.model.subProvider}` : props.providerDisplayName; Mobile uses the same field as the row subtitle, so no client change is needed once the snapshot carries it.
The rows aren't actually the same model. Slugs stay
${providerID}/${id}, so each click still routes to the right upstream; they only look identical, which matches the threeClaude Opus 5.5rows in your screenshot.model.listdoesn't include the provider's display name. The OpenCode 2 client in this build (@opencode/protocol2.0.18) returnsproviderIDon each model andnameonprovider.list, but the driver only callsmodel.listtoday:t3code/apps/server/src/provider/Drivers/OpenCodeDriver.ts
Lines 301 to 314 in 8ed276c
const loadOpenCode2Models = yield* makeOpenCode2ModelLoader( openCode2Server.withConnection((connection) => connection.client.model.list({ location: { directory: serverConfig.cwd } }).pipe( Effect.map((models) => models.data), Effect.mapError( (cause) => new OpenCodeRuntime.OpenCodeRuntimeError({ operation: "model.list", detail: "The OpenCode server could not list its models.", cause, }), ), ), ), A fix should join
provider.list'snameonto each model assubProvider, falling back toproviderIDwhen a provider has no name. The raw id alone would separate the rows (OpenCode · anthropic) but wouldn't match the display names the 1.x path shows. Open PR #14941 fixes the same omission for Pi but doesn't cover OpenCode. The existing OpenCode 2 catalog test never assertssubProvider, so a case with one shared model name across two provider ids would lock the label in.There's no workaround in the picker for now, since the slug isn't shown on the row.
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Oct 3, 2026 Thanks for the triage! I opened #14971 with the fix as described: it joins
provider.listnames onto OpenCode 2 models assubProvider, falls back toproviderID, and adds a test with one model name shared across two providers.@MaxAnderson95 thanks for the fix in #14971. I opened #15327 for the same issue and wanted to clarify the overlap and additional coverage.
Both PRs retrieve provider names from OpenCode 2 and use them to distinguish model rows. Both support arbitrary configured provider names.
#15327 also shows the provider in the selected model label after the picker closes, supports searching by provider name or raw provider ID when name metadata is missing, and updates selected labels in the web/desktop and mobile composer and mobile scheduled-task settings. I verified provider switching in the running web client. #14971 includes actual iOS verification; #15327 has not been tested on-device.
If maintainers prefer to merge the smaller server fix in #14971 first, we can rebase #15327 onto it and retain the additional selected-label and search changes. Those changes could also be cherry-picked if preferred. Happy to coordinate to avoid duplicating the server fix.
Separately, #15202 fixes a startup race that can leave custom providers out of OpenCode's returned catalog. #15327 displays provider identity for models present in that catalog; it does not fix missing models caused by that race. I have kept that discovery fix separate under the one-problem-per-PR scope.


Before submitting
Area
apps/server
Steps to reproduce
Expected behavior
Each row shows
OpenCode · <provider>, the same as OpenCode 1.x did, so models with the same name from different providers can be told apart.Actual behavior
Every row shows only
OpenCode. A model served by several connected providers appears as several identical rows (threeClaude Opus 5.5rows in my case), with nothing in the picker to say which provider each one uses.checkOpenCode2inapps/server/src/provider/Layers/OpenCodeProvider.tsbuilds the model list withoutsubProvider, while the OpenCode 1.x path (flattenOpenCodeModels) sets it from the provider's display name. #14941 fixes the same missing field for Pi.Impact
Minor bug or occasional failure
Version or commit
0.0.46-nightly.20261003.2610 (same code on main @ 8ed276c)
Environment
macOS 27.0, web client, OpenCode 2.0.22
Screenshots, recordings, or supporting files
Workaround
None.