anomalyco / anomalyco/opencode
HTTP Error 403: Forbidden if user agent starts with `Python-urllib`
Open
@kitlangton is already working on this.
Since Jul 28, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
The OpenCode Go server drops chat completion requests if the user agent HTTP header field starts with Python-urllib. This check is done before the API key is checked, which might narrow down your search for the source of this behavior.
Code to reproduce
import os, json, urllib.request
api_key = "sk-your-api-key-here"
url = "https://opencode.ai/zen/go/v1/chat/completions"
data = json.dumps({
"model": "deepseek-v4-flash",
"messages": [{"role": "user", "content": "List 10 digits of pi."}],
}).encode("utf-8")
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + api_key,
"User-Agent": "Python-urllib", # Change user agent to anything else (e.g. "asdf") and it begins to work
}
request = urllib.request.Request(url, data=data, headers=headers, method="POST")
with urllib.request.urlopen(request) as r:
print(json.load(r))
Running this code will result in urllib.error.HTTPError: HTTP Error 403: Forbidden.
If you change the User-Agent to anything else, e.g. asdf, the error will be urllib.error.HTTPError: HTTP Error 401: Unauthorized.
If you also set api_key to a valid OpenCode Go key, the server will respond correctly.
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.