anomalyco / anomalyco/opencode
[BUG]: Zen and Go expose identically-named models; picking the Zen one tells Go subscribers to "subscribe to Go" — and if it happens during compaction the session wedges permanently
@MrMushrooooom is already working on this.
Since Aug 12, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
Two separate things combine here, and I think they explain a large share of the "I paid for Go and it still says Free usage exceeded, subscribe to Go" reports (#36265, #42013, #42008, #42019, #40078, #34483, #39310, #31008, #29020, #27492 …). I could reproduce and measure both on macOS with Desktop 1.18.16.
1. opencode (Zen) and opencode-go are two providers with overlapping model names
From the local catalogue (~/.cache/opencode/models.json) on my machine:
| provider id | label | models |
|---|---|---|
opencode |
OpenCode Zen | 88 |
opencode-go |
OpenCode Go | 24 |
16 of the 24 Go models have an identically named twin in Zen — deepseek-v4-flash, deepseek-v4-pro, glm-5, glm-5.1, glm-5.2, gpt-5.6-luna, grok-4.5, kimi-k2.5, kimi-k2.6, kimi-k2.7-code, kimi-k3, minimax-m2.5, minimax-m2.7, minimax-m3, qwen3.5-plus, qwen3.6-plus. In the model picker they are the same string. Their billing is not:
opencode/<model>-free→ free tier → 429 → UI renders it asFree usage exceeded, subscribe to Goopencode-go/glm-5.2→ the Go subscription → works
Buying Go and connecting the OpenCode Go provider does not move an existing session onto it. In my log, after Go was connected, the counters were:
189 providerID=opencode <- Zen
0 providerID=opencode-go <- Go, never used
So the client kept billing Zen, and the UI kept telling me to subscribe to a plan I had already bought. That is, I believe, what most of the "subscription not linked" reports actually are — the purchase is fine, the request never reaches Go.
Suggested fix: disambiguate the two providers in the picker (they render as the same name today), and make the free-tier 429 message say which provider was billed instead of unconditionally advising "subscribe to Go" — the advice is wrong for everyone who already has Go.
2. If that failure lands during compaction, the session is wedged for good
This is the part that makes it unrecoverable rather than annoying.
level=INFO message=stream providerID=opencode modelID=<zen-free-model> session.id=ses_xxx agent=compaction mode=primary
level=ERROR message="stream error" providerID=opencode modelID=<zen-free-model> session.id=ses_xxx agent=compaction mode=primary
error.error="AI_APICallError: Error from provider (Console): Rate limit exceeded. Please try again later."
Observed behaviour:
- It is the compaction agent that is stuck, not the chat turn. My session ran fine for three hours (102 stream calls,
agent=build). Compaction fired, hit the limit, and never recovered. - Exponential backoff with no ceiling I could see. Measured gaps: 5s, 9s, 17s, 33s, 65s, 129s, 257s. This is where
retrying in 32969s - attempt #1in #36265 comes from. - It survives restarting the app. Same session, four distinct
run=ids across three restarts in one morning; each new process resumes the same pending compaction against the same model. - While the loop is in flight, the model picker has no effect. I selected a different model; its name does not appear in the log a single time while the loop was running. Only after an explicit abort did the next compaction attempt actually use the newly selected model.
- State in
opencode.db: the assistant message for the compaction exists withtime.completed = nulland zero parts — an empty placeholder retried forever, with the next user message queued behind it.
So from the user's side: restart doesn't help, switching models doesn't help, buying Go doesn't help. All three are true and all three look like "the subscription is broken".
Suggested fix: cap the compaction retries and surface a terminal, actionable error instead of retrying forever; re-read provider/model (and credentials) on each retry rather than pinning them for the lifetime of the loop.
Workaround for anyone stuck right now
- Press the stop button in the wedged session — the retry loop ignores the picker until you do.
- Switch to a model from the OpenCode Go group (not the identically-named Zen one).
- Compaction then completes and the session continues.
Verified on my machine: the session ran normally for ~3h (102 stream calls, agent=build), then sat in the wedged compaction loop for another ~3h across three app restarts — 74 failed attempts. After pressing stop and selecting glm-5.2 from the OpenCode Go group, the log switched to providerID=opencode-go, the compaction completed on the first try, and the session resumed: 7 completed assistant messages in 45 seconds, 0 errors.
Related: #30229 (-free models staying capped under Go) covers the entitlement side; #27924, #15533, #30443 cover other compaction loops.
Plugins
None relevant (context7 MCP only).
OpenCode version
1.18.16 (Desktop)
Steps to reproduce
- Connect the OpenCode Zen provider with an API key from a workspace with no balance.
- Start a session on a Zen
-freemodel and work until the context fills. - Let auto-compaction fire while the free-tier limit is exhausted.
- Observe:
Free usage exceeded, subscribe to Go, retrying with growing backoff. - Subscribe to Go, connect the OpenCode Go provider, restart the app, change the model in the picker → the loop continues unchanged against the original Zen model.
Screenshot and/or share link
Log excerpts inline above (session/workspace identifiers redacted).
Operating System
macOS 26.0.1
Terminal
OpenCode Desktop (no terminal)
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.