Skip to content

[Bug] Streaming requests to opencode.ai hang with HTTP/2 SSE (200s timeout → 502/499, Codex stuck on 'thinking') #1668

Description

@flyinsz

Client or integration

  • Codex CLI
  • Direct HTTP/API client (curl)

Area

  • Proxy and routing
  • Streaming

Summary

Requests proxied to opencode.ai (/zen/go/v1) hang forever in streaming mode (stream: true). The proxy waits the full 200s timeout, then reports connection reset / 502 upstream_server_error / 499 client_closed_request. On the client side (Codex CLI) the UI just shows "thinking" indefinitely.

This is not a proxy/DNS/network issue on the user's machine — all direct connections work fine. It is a protocol-level incompatibility between Bun's HTTP/2 fetch and the Cloudflare edge in front of opencode.ai for SSE streaming responses.

Reproduction

Same endpoint, same payload, only the HTTP version differs:

# HTTP/1.1 + stream=true  → WORKS (SSE flows, ~3s)
curl --http1.1 -N https://opencode.ai/zen/go/v1/chat/completions \
  -H "Authorization: Bearer <key>" -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"hi"}],"max_tokens":5,"stream":true}'
# → HTTP 200, SSE chunks received

# HTTP/2 + stream=true   → HANGS (no bytes at all, times out)
curl --http2 -N https://opencode.ai/zen/go/v1/chat/completions \
  -H "Authorization: Bearer <key>" -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"hi"}],"max_tokens":5,"stream":true}'
# → 0 bytes until client timeout (20s+)

# Bun fetch + stream=true (what opencodex actually does) → HANGS
# Bun's fetch negotiates HTTP/2 by default with this origin.

Non-streaming (stream: false) works over both HTTP/1.1 and HTTP/2 (~2s).

opencodex forwards all chat completions with stream: true (confirmed via ocx debug provider logs):

[ocx:openai-chat:request] {"host":"opencode.ai","model":"deepseek-v4-flash","stream":true,...}

Version

2.15.0 (@bitkyc08/opencodex, bundled Bun 1.3.14, node_modules/bun/bin/bun.exe)

Operating system

macOS (darwin)

Provider and model

opencode.ai (opencode-gohttps://opencode.ai/zen/go/v1, adapter openai-chat) / deepseek-v4-flash; Codex runtime: codex 0.147.0-alpha.6.5 (ChatGPT.app); outbound: direct connection (NO_PROXY set, no proxy vars).

Logs or error output

  • service.log: repeated [upstream-retry] connection reset (opencode.ai) — retrying (2/3)
  • usage.jsonl (recent, ~100 requests): status=502 durationMs≈200000 errorCode=upstream_server_error and status=499 closeReason=client_cancel (client abandons after ~90–160s)
  • Provider model discovery (GET /models) succeeds; only the streaming POST hangs.

Redacted configuration

{
  "provider": "opencode-go",
  "baseURL": "https://opencode.ai/zen/go/v1",
  "adapter": "openai-chat",
  "model": "deepseek-v4-flash"
}

Expected behavior

Streaming responses from opencode.ai should work over whatever HTTP version Bun negotiates. Either:

  1. opencodex should force HTTP/1.1 for SSE upstreams (Bun fetch supports protocol: "http1.1"/"h1"), or
  2. expose a config option to force HTTP/1.1 per provider, or
  3. investigate whether opencode.ai's Cloudflare edge is misbehaving with HTTP/2 SSE.

Notes

  • Verified the opencodex process connects directly to 172.65.90.20:443 (opencode.ai real IP, Cloudflare range) — no system/HTTP proxy involved. macOS system proxy (FlClash :7890) was ruled out via lsof and side-by-side tests.
  • Reproducible with both opencode-zen and opencode-go (same origin opencode.ai).
  • Worth checking if other Cloudflare-fronted SSE providers are affected by Bun's HTTP/2 fetch too.

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstreamingSSE, WebSocket, terminal stream frames

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions