anomalyco / anomalyco/opencode
xai: grok-4.6 websocket 1006 kills session drain
@rekram1-node is already working on this.
Since Sep 12, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
xAI Grok 4.6 Responses WebSocket drops mid-turn with close code 1006. OpenCode classifies this as provider.transport, SessionRunner.drain fails, and the TUI surfaces Error: WebSocket closed with code 1006 instead of retrying or falling back to HTTP.
Environment
- opencode version: 2.0.2
- OS: Darwin 24.6.0 (darwin arm64)
- Terminal: TERM_PROGRAM=ghostty, TERM=xterm-256color, COLORTERM=truecolor
- Shell: /opt/homebrew/bin/fish
- Install/channel: latest
- Active plugins:
@mohak34/opencode-notifier@latest(global); local TUI pluginherdr-tui-session.js(unrelated)
Reproduction
Intermittent. Observed three times in one evening on long xai/grok-4.6 sessions with many tool rounds.
- Use model
xai/grok-4.6(variantmedium) in the TUI against the shared background service. - Run a long agent turn with many tool calls (local shell / MCP). Context grows; xAI Responses WebSocket stays open for the session.
- Mid-step, the provider socket closes abnormally.
- TUI shows
Error: WebSocket closed with code 1006. The turn ends. Sending another prompt /continuecan resume later, but the in-flight step is lost.
Expected Behavior
A transient WebSocket 1006 during an in-flight xAI Responses stream should be treated as retryable transport (AI.Error.Transport, operation: "read"):
- If no assistant output has been committed, retry or fall back to HTTP (same idea as the SSE workaround / OpenAI WS retry path).
- If partial output already streamed, do not replay; surface a continue-after-partial-output path instead of killing drain.
- Docs currently say a closed socket reconnects on the next step and a failed open falls back to HTTP. Mid-stream close should not hard-fail
SessionRunner.drain.
Actual Behavior
Server log (role=server):
level=ERROR message="Failed to drain Session"
cause="AI.Error: WebSocket closed with code 1006
[cause]: AI.Error.Transport: WebSocket closed with code 1006
at SessionStep.attempt
at SessionRunner.runStep
at SessionRunner.drain"
Persisted assistant message:
{
"finish": "error",
"error": {
"type": "provider.transport",
"message": "WebSocket closed with code 1006"
},
"model": { "id": "grok-4.6", "providerID": "xai", "variant": "medium" }
}
A sibling failure on the same session was stored as "message": "Session WebSocket closed" (provider.transport).
TUI displays the transport error verbatim. This is not the TUI losing its local OpenCode service WebSocket.
Observed in session_v2 (local DB, redacted paths):
| session | idle_outcome | error time (UTC) | message |
|---|---|---|---|
| ses_f692903d5ffe… | interrupted | 2026-09-12 18:22:14 | WebSocket closed with code 1006 |
| ses_f6922555dffe… | failed | 2026-09-12 18:26:14 | Session WebSocket closed |
| ses_f6922555dffe… | failed | 2026-09-12 18:31:20 | WebSocket closed with code 1006 |
Drops happened ~5–6 minutes into the session, so not xAI’s documented 25-minute socket cap. Same machine previously recorded xAI ECONNRESET / ENOTFOUND as provider.transport on grok-4.5.
Additional Context
- OpenCode v2 keeps one Responses WebSocket per session for OpenAI / xAI / Azure. xAI default
store: falsesends each step in full over the reused connection. - WebSocket 1006 = abnormal TCP close, no close frame (RST, proxy idle, peer drop). Cannot be sent as a close code.
- Related: #29646 (OpenAI WS 1006 should retry/HTTP-fallback; closed as not planned). #42572 / #43100 cover 1009 oversized-message HTTP fallback, which does not cover 1006.
- Local workaround that should work:
"providers": { "xai": { "websocket": false } }(not verified in this report). - User workaround: send
continueafter the error. Does not recover the failed step. - Project
opencode.jsonhad nowebsocketoverride (xAI WS left at built-in default). - Service was healthy (
opencode service status→http://127.0.0.1:49374).opencode --version= 2.0.2.
Suggested fix: classify mid-stream xAI/OpenAI WS close 1006 as retryable Transport before drain failure; HTTP-fallback when no output committed; reconnect-or-continue when output already streamed.
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.