You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
OpenCode V2 workspace starts with an empty credential store, so every run fails with provider-auth-unavailable #1992
On v0.130.0 with the OpenCode V2 workspace (OPENCODE_VERSION 2.2.0 from opencode-v2-pin.json), every run fails about 9 seconds in with providerFailureReason: provider-auth-unavailable. The V2 server has no provider credential, so every model call goes out without a key and the provider answers 401.
Evidence (production, read-only)
The run status frames carry failureKind: session-error and providerFailureReason: provider-auth-unavailable. In the gateway log, provider retry scheduled is followed by session.execution.failed (provider auth unavailable) and then provider rejected the request — failing run. This happens on every repository.
The egress proxy shows the workspace reaching the provider. POST https://<provider>/v1/messages?beta=true returned 401 Unauthorized 12 times.
The legacy credential file exists. /home/opencode/.local/share/opencode/auth.json is mode 600, owned by uid 10001, with top-level keys anthropic and openai. The entrypoint logged auth: provisioned.
The V2 server (opencode serve --stdio, uid 10001) runs with XDG_DATA_HOME=/home/opencode/.local/share and a fresh OPENCODE_DB=/var/lib/workspace-agent/opencode-v2-db/spawn-*/opencode.db. That database's credential table is empty: SELECT integration_id, count(*) FROM credential GROUP BY 1 returns no rows. The workspace log has no credential-import line or error.
OPENCODE_CONFIG_CONTENT has no provider key and no model, but the workspace log reports model=set, provider-overlay=applied. I haven't found where the V2 server reads that overlay.
On v0.129.0 (V1, OpenCode 1.19.4) the same credential file and provider config worked, and runs reached the model.
Expected
A V2 spawn should end up with the provisioned credentials in its credential store. Either the legacy auth.json import runs against the fresh per-spawn database, or the workspace writes the credential into the V2 store directly. It should fail loudly at spawn when the store is empty, not at the first model call.
Related
V2 2.2.0 also fetches its model catalog from models.opencode.ai, which the egress allowlist blocks (403). It falls back to the bundled snapshot. That's a separate issue, and I'm handling it on the deploy side.
Recommended priority: P1. The reported fleet-wide model failures are consistent with a locally reproduced V2 credential-provisioning defect.
Root cause
OpenCode 2.2.0 has a legacy auth.json importer, but fresh databases skip it:
In upstream DatabaseMigration.apply, an empty database receives the current schema and every migration is recorded as completed, without executing the individual migration bodies.
Our workspace creates a fresh database for every spawn, while provisioning writes only the legacy file. No provider-credential gate runs before readiness. The supervisor's “credential holder” contains the server's Basic authentication password, not provider keys.
This explains both the empty table and the absence of an import log. Restarting repeats the failure.
Reproduction
Using the checksum-verified stock 2.2.0 Linux binary, an isolated HOME/XDG tree, dummy Anthropic/OpenAI keys, and the production provisioning helper:
Provisioned auth.json and a provider/model overlay before starting the server.
Started serve --stdio against a fresh OPENCODE_DB.
Observed /api/agent ready, /api/credential empty, and the legacy-import migration recorded complete.
Verified POST /api/credential successfully stored and activated a dummy key.
Repeated with another fresh database: credentials were empty again.
The overlay is being read:/api/config exposed the provider URL and model from $XDG_CONFIG_HOME/opencode/opencode.json, although neither appeared in OPENCODE_CONFIG_CONTENT. That omission alone is not a configuration failure.
This reproduces the credential loss/readiness defect; I did not replay a production provider request or independently reproduce its 401. Focused existing tests passed: 91 passed, with 2 real-binary integration tests skipped. The standalone reproduction above exercised the downloaded binary. Existing workspace integration coverage embeds an apiKey directly in provider options, bypassing this legacy-file path.
Next steps
Seed credentials on every V2 spawn, preferably through the authenticated POST /api/credential API before publishing readiness. Convert legacy API entries from {type: "api", key} to V2 {integrationID, value: {type: "key", key}}; keep secrets out of argv and logs.
Verify the provisioned credentials are active before admitting model runs; emit a clear provisioning failure instead of deferring to the first request. Preserve credential-free clone-only boot.
Add a regression test using legacy-file-only credentials, two fresh spawns, and a local provider that asserts the received authentication header.
Report the fresh-bootstrap importer omission upstream. Keep the model-catalog egress issue separate.
Activity
fro-bot commentedon Oct 30, 2026
Triage: confirmed credential-bootstrap regression
Recommended priority: P1. The reported fleet-wide model failures are consistent with a locally reproduced V2 credential-provisioning defect.
Root cause
OpenCode 2.2.0 has a legacy
auth.jsonimporter, but fresh databases skip it:DatabaseMigration.apply, an empty database receives the current schema and every migration is recorded as completed, without executing the individual migration bodies.import_legacy_credentialsmigration is therefore marked complete without readingauth.json.This explains both the empty table and the absence of an import log. Restarting repeats the failure.
Reproduction
Using the checksum-verified stock 2.2.0 Linux binary, an isolated HOME/XDG tree, dummy Anthropic/OpenAI keys, and the production provisioning helper:
auth.jsonand a provider/model overlay before starting the server.serve --stdioagainst a freshOPENCODE_DB./api/agentready,/api/credentialempty, and the legacy-import migration recorded complete.POST /api/credentialsuccessfully stored and activated a dummy key.The overlay is being read:
/api/configexposed the provider URL and model from$XDG_CONFIG_HOME/opencode/opencode.json, although neither appeared inOPENCODE_CONFIG_CONTENT. That omission alone is not a configuration failure.This reproduces the credential loss/readiness defect; I did not replay a production provider request or independently reproduce its 401. Focused existing tests passed: 91 passed, with 2 real-binary integration tests skipped. The standalone reproduction above exercised the downloaded binary. Existing workspace integration coverage embeds an
apiKeydirectly in provider options, bypassing this legacy-file path.Next steps
POST /api/credentialAPI before publishing readiness. Convert legacy API entries from{type: "api", key}to V2{integrationID, value: {type: "key", key}}; keep secrets out of argv and logs.Run Summary