Repository navigation
Description
Description
Free-tier models return HTTP 403 FreeTierError for one specific existing session, and for every session forked from it — including an empty fork with 0 messages. Brand-new sessions in the same project, with the same agent and model, work fine at the same moment. The request is rejected before inference (1-2 s, no tokens billed).
Affected session: ses_Ddv16i0l55Ptn7tNW6rUg3wL4n (agent plan, model opencode/deepseek-v4.1-flash-free, Desktop app)
Working session, same project/agent/model: ses_eaad33c23ffenS4T2nmgVFA9uo
OpenCode version
- Desktop app / background service:
2.0.32(the app auto-updated from 2.0.29 during the session) opencode --versionon PATH:opencode v2.0.29
Plugins
- Local plugin
~/.config/opencode/plugins/telegram-notify/index.ts(Telegram notifications only; it just callsapi.telegram.org) - MCP server: managed
opencode_console
Steps to reproduce
- Open the affected session (agent
plan, modelopencode/deepseek-v4.1-flash-free) and send any prompt. It fails immediately withprovider.auth/ 403FreeTierError. - Create a new session in the same project with the same agent and model, send any prompt. It works.
- Fork the affected session with the boundary before its first message, so the fork contains 0 messages:
POST /api/session/ses_Ddv16i0l55Ptn7tNW6rUg3wL4n/fork {"before":"msg_ACMnLTgMFhyO8uSbCKwNFs6lnl"}
The fork inherits agent and model but has no history. - Send any prompt in that empty fork. Same 403
FreeTierError. - Fork a working session the same way (0 messages) and send the same prompt. It succeeds.
- Interleaved A/B a few seconds apart: the empty fork of the affected session fails twice; the empty fork of the working session succeeds.
Fork IDs from the test: empty fork of affected session ses_eaacdd467ffe7DOLmo7WxQXFZ2 (fails), empty fork of working session ses_eaaca25c0ffeIm6xrwEzvSKsDR (succeeds).
Actual behavior
Stored message error:
{"type":"provider.auth","message":"OpenCode's free tier can only be used from within OpenCode. Download it at https://opencode.ai and keep building.","status":403,"response":{"body":"{\"type\":\"error\",\"error\":{\"type\":\"FreeTierError\",\"message\":\"OpenCode's free tier can only be used from within OpenCode. Download it at https://opencode.ai and keep building.\"}}"}}Server log (~/.local/share/opencode/log/opencode.log):
timestamp=2026-10-19T17:12:47.821Z level=ERROR message="Failed to drain Session" cause="AI.Error: OpenCode's free tier can only be used from within OpenCode..." role=server sessionID=ses_Ddv16i0l55Ptn7tNW6rUg3wL4n
timestamp=2026-10-19T17:13:26.224Z level=ERROR message="Failed to drain Session" cause="AI.Error: OpenCode's free tier can only be used from within OpenCode..." role=server sessionID=ses_Ddv16i0l55Ptn7tNW6rUg3wL4n
Expected behavior
A session created and used by the official client keeps working on the free tier, and forking a session does not propagate a rejection.
What I ruled out
- Model: fails with
deepseek-v4.1-flash-freeandglm-5.3-flash-free. A paid model (opencode/deepseek-v4.1-flash) in the same session gets past the free-tier gate and returnsprovider.quota"Insufficient account funds", so the request is attributed to the account normally. - Agent: fails with both
planandbuild. - History / context size: an empty fork (0 messages) still fails.
- Session
permissions: the affected session carries a saved permission[{"action":"browser","resource":"*","effect":"allow"}];PATCH /api/session/<id> {"permissions": []}cleared it and the session still failed. - Timing / flakiness: interleaved A/B seconds apart, fails every time.
- Account / workspace: free models are enabled and available in the workspace, and other free-model sessions in the same project work.
Possible lead: this session was exported (opencode session export ses_Ddv16i0l55Ptn7tNW6rUg3wL4n) and resumed with opencode -s ses_Ddv16i0l55Ptn7tNW6rUg3wL4n on 2026-10-18, the day before it started failing.
Operating System
Windows 11 Home, 10.0.26300 (x64)
Terminal
OpenCode Desktop app (CLI checks run from Windows PowerShell 5.1)
Activity
opencode-agent commentedon Oct 19, 2026
Thanks for the very thorough report. The A/B testing with empty forks made this much easier to pin down.
I think this is a duplicate of #55476. In that issue, the free-tier gateway was shown to reject sessions whose ID isn't in OpenCode's native format. A native ID is
ses_+ 12 hex characters (an inverted timestamp) + 14 letters/digits. Your working sessionses_eaad33c23ffe…has that format. The affectedses_Ddv16i0l55Ptn7tNW6rUg3wL4ndoesn't, and neither does its first messagemsg_ACMnLTgMFhyO8uSbCKwNFs6lnl: their prefixes aren't hex. The client can't generate IDs like that, so the session most likely came from an import, which fits your lead about the export and resume.This also explains why even empty forks fail. For provider cache routing, a fork sends its source session's ID in the
x-opencode-session/x-session-affinityheaders (packages/core/src/session/affinity.ts). So the gateway still sees the invalid ID, even though the fork's own ID is valid. That's a useful detail for #55476, so feel free to add it there.Until that's fixed, a workaround is to start a new session rather than forking this one.
Possible duplicates and related issues, ordered by likelihood:
bash: deny).The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
Tarquinen commentedon Oct 20, 2026
Thanks for the report! This looks like the same problem as #55476, so I'm closing this as a duplicate. Please follow that issue for updates.
— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
opencode-agent commentedon Oct 20, 2026
Closing this as a duplicate of #55476, since there's been no reply in the past day. The session ID
ses_Ddv16i0l55Ptn7tNW6rUg3wL4nisn't in OpenCode's native format, and the free-tier gateway rejects IDs like that. Empty forks fail too because a fork sends its source session's ID in the affinity headers.Please follow #55476 for updates. Your finding that even empty forks inherit the rejection would be a useful comment there. Until it's fixed, starting a new session instead of forking this one works around it. If your problem turns out to be different, reply here and we can reopen.