anomalyco / anomalyco/opencode

GUI: V2 protocol doesn't show providers as connected when apiKey is in config file

Open
#39,076 0 comments 0 reactions 1 assignee View on GitHub

@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

  1. Create a project-level opencode.jsonc with a provider config:
{
  "provider": {
    "opencode": {
      "options": {
        "apiKey": "sk-xxx"
      }
    }
  }
}
  1. Start the OpenCode server (the V2 /api/provider endpoint is served alongside V1).
  2. Open the GUI (Desktop or Web). The GUI detects V2 protocol.
  3. Go to Settings → Providers.
  4. OpenCode appears in the "Popular" section with a "Connect" button, not in "Connected providers".
  5. Running the same setup with OPENCODE_API_KEY env 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.apiKeyrequest.body.apiKey server-side, so no config changes are needed.

Environment:

  • OpenCode version: 1.18.7
  • GUI: Desktop / Web
  • Protocol: V2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.