Repository navigation
Description
Area
apps/server
Steps to reproduce
- Store an OpenCode Go API key that has since expired. Either
opencode auth loginwith a Go key (OpenCode 2 importsauth.jsoninto thecredentialtable) orOPENCODE_API_KEY. - Run OpenCode locally in an environment (Server URL empty) with the instance enabled.
- Open Usage → Limits and refresh.
Expected behavior
The notice says why: OpenCode rejected the Go API key because it expired or was revoked. It also says what to do: create a new key in OpenCode Console, then sign in with it again or set OPENCODE_API_KEY.
Actual behavior
Every environment shows OpenCode: OpenCode Go could not read usage. That is the same text as a timeout, a network failure, or an unexpected response, and it gives no hint that the key is the problem.
The endpoint already gives the reason. GET https://opencode.ai/zen/go/v1/usage with this key returns:
401 {"error":{"type":"authentication_error","code":"api_key_expired","message":"This API key has expired. Create a new API key in OpenCode Console and replace it in your client or secret store. Signing in again will not renew this key."}}
readOpenCodeGoUsageLimits (packages/provider-opencode/src/server/usageLimits.ts) special-cases only 403 (no Go subscription). filterStatusOk turns a 401 into an error, and Effect.orElseSucceed replaces it with the generic probeFailed message.
Impact
The user cannot tell an expired key, which only they can fix, from a transient failure that a retry might clear. With the same key on several machines, the notice repeats once per environment, and none of the lines says what to do.
Version or commit
main at 1451e7cb23
Environment
Linux and macOS environments in one pool, all local OpenCode 2.0.32 instances. opencode auth list shows OpenCode Go API key stored. There is no Console connection, so this is not the case covered by #14983, #16605, or #21007: no other credential exists to fall back to.
Workaround
Create a new Go API key in OpenCode Console, then run opencode auth login on each machine or set OPENCODE_API_KEY under Settings → Providers → OpenCode → Environment variables.
Suggested direction
When the usage endpoint returns 401, publish a probeFailed message that names the cause, for example "OpenCode Go rejected its API key (expired or revoked). Create a new key in OpenCode Console." Keep the generic message for timeouts and other failures. #21007 already retries a second key on 401/403. This message would cover the case where every candidate key is rejected.
Related
- [Bug]: Usage → Limits never reports OpenCode Go for OpenCode 2 Console logins #14983: Go limits missing for OpenCode 2 Console logins (different credential source; its comments mention the same
401 api_key_expiredin passing) - fix(server): read OpenCode Go limits key from OpenCode 2's credential database #16605, fix(server): restore OpenCode Go limits for Console API keys #21007: read OpenCode 2's credential store and the Console key
Investigated with Claude Code (Claude Opus 5.5).
Activity
juliusmarminge commentedon Oct 19, 2026
Note
Grok responding on behalf of Julius.
This is a request for a more specific message, not a bug, so I'm closing it as an idea. The probe works as written: a 401 fails
filterStatusOkand becomes the generic "could not read usage" notice (usageLimits.ts:77-79 and 115-123). The 403 case (usageLimits.ts:76) doesn't name a cause. It hides Go limits for keys without a subscription. The Grok and Cursor usage probes also use one generic failure message, and #20828 kept fixed failure strings for turn starts on purpose.For now, store a new Go key with
opencode auth login. The probe uses a key stored in auth.json beforeOPENCODE_API_KEY(usageLimits.ts:64-66), so setting only the environment variable won't replace a stored expired key.If you'd like auth-specific usage notices, please open an idea at https://github.com/pingdotgg/t3code/discussions/new?category=ideas