Repository navigation
Description
Steps to reproduce
- OpenChamber Desktop 2.0.2, macOS (Apple Silicon), using the bundled OpenCode CLI
- Settings → Providers → "Other / Custom"
- Fill in a custom provider — e.g. Provider ID
commandcode, protocolopenai-chat, display namecommandcode, base URLhttps://api.commandcode.ai/provider/v1, API key set - Save
What you expected
The custom provider is written into the OpenCode config (as the form description says) and becomes selectable in chat.
What happened instead
A toast appears: Integration not found: commandcode, and the provider is not saved. This reproduces with any custom provider ID (renaming the ID does not help).
Analysis (from the public sources — please confirm)
The save flow appears to store the API key through OpenCode's integration credential API. In the OpenCode v2 sources:
Integration.connection.key(packages/core/src/integration.ts) requires a registered integration with that exact ID, and dies withKey method not found: <id>otherwise.- Key methods are only registered for providers that exist in the models.dev catalog (
packages/core/src/plugin/models-dev.tsregisterskey/envmethods per catalog entry), plus a few plugin-defined integrations (openai,opencode, ...). - A brand-new custom provider ID is by definition not in models.dev, so this call can never succeed for the custom-provider form. (I verified the provider I tried is not in the models.dev catalog either — but any made-up ID should reproduce.)
Workaround
Hand-editing ~/.config/opencode/opencode.json works as expected:
{
"provider": {
"<id>": {
"npm": "@ai-sdk/openai-compatible",
"name": "...",
"options": { "baseURL": "...", "apiKey": "..." },
"models": { "<model-id>": {} }
}
}
}So the bug is limited to the UI save path — presumably the key should be written into the config (or via the legacy auth.set endpoint, which is what the official OpenCode desktop dialog does) for custom providers, instead of the integration-key endpoint.
Environment
- OpenChamber Desktop 2.0.2, macOS Apple Silicon
- Bundled OpenCode CLI (v2 line — not separately upgradeable from inside the desktop app)
Happy to paste openchamber status output if useful.
Activity
openchamber-bot commentedon Sep 26, 2026
For the maintainer:
fix-ready— cause tracedYour analysis is right. The save flow in
handleSaveCustomProvider(packages/ui/src/components/sections/providers/ProvidersPage.tsx:489-492) callsintegration.connect.keywith the custom provider ID before attempting the config write. OpenCode'sintegration.connect.keyendpoint rejects any ID not present in its models.dev catalog, so this call always fails for custom providers and the config write at line 502 never executes.The config write path (
PUT /api/provider→upsertProviderConfig) is designed for this — it writes provider blocks intoopencode.json— but the API key is a separate concern:upsertProviderConfigexplicitly does not write secrets (packages/web/server/lib/opencode/providers.js:203). The escape-suite tests already work around this by writing credentials directly into the SQLitecredentialtable (packages/web/server/lib/spaces/places/escape-suite.js:219-224), confirming no OpenCode API route supports key storage for non-catalog integrations.Plausible-but-unconfirmed for the reporter: the fix path would be to either (a) skip
integration.connect.keyfor custom providers entirely and store the API key via a new server-side route that writes to the SQLite credential table, or (b) embed the key into the provider config block itself (theoptions.apiKeypath in the workaround). Either way,buildIntegrationKeyRequestatcustom-provider-form.ts:622should returnnullfor custom provider IDs, and the credential storage should use a path that does not depend on the integration catalog.The upstream OpenCode issue anomalyco/opencode#51527 tracks the API-level gap. This issue stays here because the OpenChamber save flow is what triggers the failing call and the fix lives in OpenChamber.
Minimal reproduction sketch
The call chain:
validateCustomProvider()buildsCustomProviderPersistPlanwith literalapiKeybuildIntegrationKeyRequest(plan)returns{ integrationID: "my-custom", key: "sk-..." }(not null)integration.connect.key(keyRequest)throwsIntegration not found: my-customruntimeFetch("/api/provider", ...)never runsNo script needed — any custom provider ID with a literal API key reproduces this on current main.
fix(providers): save custom providers with an API key on OpenCode 2
btriapitsyn commentedon Sep 27, 2026
Fixed by 50766fa: the provider config is now written first and the key right after it, since OpenCode 2 only accepts a key for a custom provider once it's in config. The server also stopped asking for the old auth.json entry. Ships in 2.0.3; if saving still fails there, comment and we'll reopen.
sync: upstream v2.0.4 (114 commits) (#4)
fix(providers): save custom providers with an API key on OpenCode 2