anomalyco / anomalyco/opencode
Zen/Go API endpoints missing `Access-Control-Allow-Origin` on actual responses (CORS fails for browser-based clients)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
Description
The OpenCode Zen/Go endpoints (e.g. https://opencode.ai/zen/go/v1/models) do not include the Access-Control-Allow-Origin header on the actual GET/POST responses, even though the OPTIONS preflight returns one. As a result, browser-based API clients that make direct cross-origin requests (e.g. SillyTavern's character-card model query) fail with a CORS error / "Failed to fetch".
Steps to reproduce
- Open a browser-based client (e.g. SillyTavern) and make a direct fetch to
https://opencode.ai/zen/go/v1/modelsfrom an arbitrary origin (e.g.http://localhost:8000). - Observe the request fails in the browser with a CORS error.
- Compare with a provider that works, e.g.
https://api.deepseek.com/v1/models, which returnsaccess-control-allow-originon the actual response.
Curl evidence (actual GET response headers):
# opencode.ai — actual GET response has NO Access-Control-Allow-Origin
$ curl -s -o /dev/null -D - "https://opencode.ai/zen/go/v1/models" -H "Origin: http://localhost:8000"
HTTP/1.1 200 OK
Content-Type: application/json
Server: cloudflare
CF-RAY: ...-IAD
# <-- no access-control-* header at all
# api.deepseek.com — actual GET response DOES have it
$ curl -s -o /dev/null -D - "https://api.deepseek.com/v1/models" -H "Origin: http://localhost:8000"
HTTP/1.1 401 Authorization Required
access-control-allow-credentials: true
access-control-allow-origin: http://localhost:8000
Note: the OPTIONS preflight for opencode.ai does return CORS headers (Access-Control-Allow-Origin: *, access-control-allow-headers: Content-Type, Authorization), but browsers also check the actual response, which lacks Access-Control-Allow-Origin, so the request is still blocked.
Expected behavior
Actual GET/POST responses should include an appropriate Access-Control-Allow-Origin header (matching the request origin or * when credentials are not required) so that cross-origin browser clients can consume the API.
Actual behavior
Actual responses return no Access-Control-Allow-Origin, so browsers block them with a CORS error. This only works when requests are routed through a server-side proxy (same-origin), not for direct browser fetches.
Environment
Endpoint(s): https://opencode.ai/zen/v1/*, https://opencode.ai/zen/go/v1/*
Affected client: any browser-based tool doing direct cross-origin fetches (reproduced with SillyTavern v1.18 character-card API query)
### Plugins
SillyTavern v1.18 character-card API query
### OpenCode version
https://opencode.ai/zen/go/v1
### Steps to reproduce
_No response_
### Screenshot and/or share link
<img width="678" height="442" alt="Image" src="https://github.com/user-attachments/assets/4a225107-1b46-4e19-9854-a52ca72235bc" />
<img width="468" height="206" alt="Image" src="https://github.com/user-attachments/assets/687df119-5e24-4afd-ac5f-a73b0d2949aa" />
<img width="579" height="396" alt="Image" src="https://github.com/user-attachments/assets/c95e39cf-c80b-45e1-839a-67052769fc34" />
### Operating System
Windows 11
### Terminal
SillyTavern v1.18 character-card API query
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.
Research direction
Start by tracing the OpenCode Zen/Go API entry points serving /zen/v1/* and /zen/go/v1/*, then reproduce the reported behavior with the curl commands and an Origin header. The fix is complete when actual GET and POST responses include an appropriate Access-Control-Allow-Origin header and browser-based direct requests succeed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100