Repository navigation
Description
Summary
With no root model configured, OpenCode v2.2.6 resolves the implicit default model to opencode-go/hy4 whenever OPENCODE_API_KEY is present in the environment — even when that key has no active Go subscription. hy4 is the newest model in the catalog (released 2026-11-04), so release-date fallback ordering selects it. Every agent that has no explicit model (plan, general, explore, title, summary, compaction) then fails on every request:
> general · hy4
Error: An active OpenCode Go subscription is required to use Go models.
Nothing in config or api agent.list warns that the resolved default is unusable. The only signal is the failure at request time.
Environment
- opencode version:
2.2.6 - OS:
Darwin 27.2.0 arm64(macOS 27.2) - Terminal: Apple Terminal,
TERM=xterm-256color,TERM_PROGRAM=Apple_Terminal,COLORTERM=truecolor - Shell:
/bin/zsh - Install/channel: npm global,
@opencode/cli@2.2.6, Node v22.23.1 - Active plugins: local
superpowersplugin directory (reproduced with{"plugins":[]}as well, so the plugin is not involved)
Reproduction
Minimal, in an empty directory with no opencode.json, no .opencode/, no project config:
- Ensure
OPENCODE_API_KEYis set to a key whose Go subscription is expired or absent, and that no rootmodelis configured. - Run:
cd "$(mktemp -d)" opencode run --agent general "hi"
- Observe
> general · hy4followed byError: An active OpenCode Go subscription is required to use Go models.
The same failure occurs for plan, explore, title, and summary. Reproduced 3/3.
Expected Behavior
- Implicit default resolution should not select a model from a provider whose credentials cannot actually serve requests.
- If the resolved default is unusable,
api agent.list/ the TUI should show it as unresolved (or pick a working model), rather than silently reporting(inherit). - An agent without
modelshould fall back to an enabled, authorized model, or fail with an error that names the cause (no usable default) rather than a provider-specific subscription message.
Actual Behavior
opencode-go/hy4 is selected and every inheriting agent fails.
Isolation (this narrows the trigger to one env var)
All runs use --standalone, an empty temp directory, and no project config. Only the environment differs:
OPENCODE_API_KEY |
OPENCODE_CONSOLE_TOKEN |
Resolved model | Result |
|---|---|---|---|
| unset | unset | opencode-go/iceman-free |
works |
| unset | set | opencode-go/iceman-free |
works |
x (garbage) |
unset | opencode-go/iceman-free |
fails later with Reconnect OpenCode Console to continue. |
"" (empty string) |
unset | opencode-go/iceman-free |
works |
| real key, expired subscription | unset | opencode-go/hy4 |
fails: subscription required |
Two things stand out:
- A real-but-expired key is treated worse than a garbage key. Garbage
xfalls back toiceman-freeand fails with a reconnect prompt; a syntactically valid key that merely lacks an active subscription is silently promoted to becoming the default model for every unconfigured agent. - The default changes with credential validity. The resolution result differs between "no key" and "key with expired subscription", which means availability is being derived from key presence rather than from an authorized subscription.
The background service differs from --standalone in the same way: the running service process has OPENCODE_API_KEY in its environment, so opencode run --agent general (no --standalone) fails identically, while --standalone with the variable unset works.
Additional Context
Fallback ordering is affected, not just this one model
Disabling hy4 does not solve it; the next newest models are also unusable:
{"providers":{"opencode-go":{"models":{"hy4":{"disabled":true}}}}}then resolves to crouton-alpha-free, which fails with This model is not available in your country.
Disabling hy4 plus the three -free models resolves to kimi-k3.1-pro, which fails with the same subscription error.
So release-date ordering keeps walking down a list of catalog entries that are not callable in this environment. Two of the failures are not "unavailable model" errors at all but geo-restriction errors, which suggests availability checks do not consider region.
Disabling the whole provider does not work
Trying to take the provider out of the running entirely had no effect:
{"providers":{"opencode-go":{"disabled":true}}}still resolves to opencode-go/hy4. The schema for encoded providers (Config.ProviderEncoded) lists only canonical, name, env, package, compatibility, settings, headers, body, models, so a provider-level disabled key is not part of the documented shape and is silently ignored. Only per-model disabled has an effect.
Workaround
Setting an explicit root model avoids the fallback path entirely:
{"model":"<provider>/<model>"}Verified: with that set, general resolves to the configured model and runs. Removing it restores the failure. Pinning model on each individual agent also works but does not scale.
Related
- Cold-start default model is stale: substring priority list picks gemini-3-pro-preview over every newer model #39125 — v2 replaced the stale substring priority list with release-date ordering. This report is about that ordering walking into providers that cannot serve the request; the ordering change itself is working as described there.
- V2 cold-start model resolution can select an unavailable catalog provider #62194 — same shape of bug (catalog provider without usable credentials selected as default). Closed for lack of a reproduction on a released build; the environment matrix above is that reproduction.
- subagent: auto-selects a disabled model instead of respecting disabled state #58681 — subagent resolving to a disabled model. Different trigger (explicit disable), same underlying gap: availability of the resolved model is not validated.
- auth: expired Go API key error gives no recovery path and misdirects users #56586 — expired Go API key gives no recovery path. Adjacent: that issue is about the error text, this one is about an expired key silently becoming every agent's default model.
Activity
opencodejr commentedon Nov 9, 2026
Thanks for the very thorough write-up and the environment matrix. They make the cause easy to follow.
In short, you'd like the implicit default model (when no root
modelis set) to skip models your credentials can't actually use, such as Go models without an active subscription or models blocked in your region. You'd also likeagent.listand the TUI to show when the resolved default isn't usable.From the code, v2.2.6 picks the default as the newest enabled text model by release date. Paid OpenCode models are enabled whenever a key is present (
OPENCODE_API_KEYor a Console connection). The client doesn't check subscription status or region, so with your key set,opencode-go/hy4wins by release date. Since that is how the picker was built, I've filed this as a feature request rather than a bug. The maintainers will consider it.Until then:
modelin your config avoids the fallback entirely, as you found.providers.<id>.disabledisn't a supported key, which is why it had no effect. Provider-level disabling goes throughpolicies. I've checked this in the code but haven't run it:{ "policies": [ { "action": "provider.use", "resource": "opencode-go", "effect": "deny" } ] }"disabled_providers": ["opencode-go"]is converted into the same policy.Related issues:
Model.smallchoosing a metered model over a free one