anomalyco / anomalyco/opencode
GUI: V2 protocol doesn't show providers as connected when apiKey is in config file
@Brendonovich is already working on this.
Since Jul 27, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Describe the bug
When using a V2 protocol connection (e.g. OpenCode Desktop or Web UI), providers configured via opencode.jsonc with provider.<name>.options.apiKey show as not connected. Their paid models are unavailable.
This works correctly under the V1 protocol. It also works for providers whose keys come from environment variables or the auth store.
To Reproduce
- Create a project-level
opencode.jsoncwith a provider config:
{
"provider": {
"opencode": {
"options": {
"apiKey": "sk-xxx"
}
}
}
}
- Start the OpenCode server (the V2
/api/providerendpoint is served alongside V1). - Open the GUI (Desktop or Web). The GUI detects V2 protocol.
- Go to Settings → Providers.
- OpenCode appears in the "Popular" section with a "Connect" button, not in "Connected providers".
- Running the same setup with
OPENCODE_API_KEYenv var shows OpenCode as connected.
Root Cause
The V2 provider API returns ProviderV2Info[] where apiKey lives in request.body.apiKey (and provider options like baseURL live in api.settings). The normalizeProviderList function in packages/app/src/context/global-sync/utils.ts (line 82) only reads provider.settings — which doesn't exist on ProviderV2Info — so options is always {}:
options: provider.settings ?? {}, // undefined for V2 → empty object
This drops apiKey and other configuration from the normalized Provider object. The connected-provider filter in the settings UI also checks for opencode models with non-zero cost (line 52 of settings-v2/providers.tsx); without an apiKey the server strips paid models, so no models satisfy the filter and the provider is excluded from the connected list.
Expected behavior
Providers configured via opencode.jsonc with V1-style options.apiKey should appear as connected in the GUI, with their paid models available.
Proposed Fix
In packages/app/src/context/global-sync/utils.ts, change line 82 to merge both api.settings and request.body into the options bag:
options: {
...provider.api?.settings,
...provider.request?.body,
} ?? {},
The V1→V2 config migration already correctly converts options.apiKey → request.body.apiKey server-side, so no config changes are needed.
Environment:
- OpenCode version: 1.18.7
- GUI: Desktop / Web
- Protocol: V2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.