Repository navigation
[Bug]: opencode-free: all free models fail with permission_denied from the Codex App #7255
Description
Client or integration
Codex App
Provider or upstream service
opencode-free (https://opencode.ai/zen/v1)
OpenCodex version
2.86.0 (npm global @bitkyc08/opencodex; OpenCodex desktop app on macOS)
Endpoint or capability
/v1/chat/completions via the opencode-free provider (every free model tried; failures captured for opencode-free/ll-alpha-free)
Current behaviour
Using OpenCodex as the provider proxy in front of the Codex App, every opencode-free model fails with permission_denied. The error appears on the first message, for every free model tried, so the entire free tier is unusable through OpenCodex. Proxy logs show 12 consecutive 403 permission_denied failures (headers-only / credential-rejected) on 2026-10-16; redacted evidence in the comments.
Expected behaviour
opencode-free models should return a normal completion (cost 0) from the Codex App through OpenCodex, as they did after the fix in #4136.
Minimal redacted request or reproduction
# Standard request shape sent by the Codex App through the local OpenCodex proxy.
# Exact outgoing request was not captured; this is the reproducible shape.
curl http://127.0.0.1:<port>/v1/chat/completions \
-H "Authorization: Bearer <REDACTED>" \
-H "Content-Type: application/json" \
-d '{"model":"<any opencode-free model>","messages":[{"role":"user","content":"hi"}]}'Reproduces on every free model, on the first message, with no special configuration.
Actual response or error
The Codex App surfaces exactly permission_denied for every opencode-free model; no response is generated. Proxy-side records confirm: upstream HTTP 403, error code permission_denied, failure stage headers-only, failure cause credential-rejected (see redacted log excerpt in the comments). The raw upstream response body was not logged. For reference, the same gate in #4121 returned MissingSessionID / "OpenCode's free tier can only be used in OpenCode", so this may be the same Zen free-tier check surfacing under a different client-side error string.
Upstream documentation
Suggested mapping or implementation notes
Possibly related to #4121 (Zen free-tier gate rejecting non-OpenCode clients, fixed by #4136). A comment there from 2026-09-14 (OpenCodex 2.54.0) reported the upstream gate still triggering on some free routes; this report suggests it now affects all free models from the Codex App. Control: opencode-go requests from the same proxy returned 200 on 2026-10-12, so the failure is specific to the opencode-free provider.
Checks
- I searched existing provider and compatibility issues.
- The request and response were redacted.
- The expected behaviour is based on an upstream specification or a concrete client requirement.
Activity
github-actions commentedon Oct 16, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
Guns160 commentedon Oct 16, 2026
Redacted evidence from the local proxy logs (OpenCodex 2.86.0, macOS, npm global install). Nothing sensitive below: request/conversation ids are truncated, and no tokens or message contents are included.
All 12 failures occurred within a single session on 2026-10-16, 23:17:31-23:17:42 (+0800), immediately after selecting the model in the Codex App:
opencode-free/opencode-free/ll-alpha-free403permission_deniedheaders-onlycredential-rejectedresponses(Codex App), translatedresponses -> chat(cross-wire-ir)openai-chatxhigh(reasoning_effort)explicit-provider-namespace(model picked explicitly in the client)sendCount: 1each, no recoverySample redacted attempt record (from the proxy usage log):
{ "requestId": "ocx-ed30bf5b...(truncated)", "provider": "opencode-free", "model": "ll-alpha-free", "requestedModel": "opencode-free/ll-alpha-free", "inboundProtocol": "responses", "status": 403, "errorCode": "permission_denied", "attempts[0]": { "adapter": "openai-chat", "status": 403, "errorCode": "permission_denied", "failureStage": "headers-only", "failureCause": "credential-rejected", "sendCount": 1, "recoveryKinds": [] } }Two observations that may help debugging:
headers-only/credential-rejectedmeans the upstream Zen gate rejected the request from the headers alone, matching the opencode-free: Zen rejects requests without x-opencode-session (free tier lock-in) #4121 pattern (free-tier provenance check), even though this run is on 2.86.0, well after the docs(provider): explain the opencode-free Zen lock-in instead of leaking MissingSessionID #4136 fix.opencode-goprovider (opencode-go/deepseek-v4.1-flash) returned 200 on 2026-10-12 from the same proxy. Onlyopencode-freefails.