Skip to content

Codex WebSocket transport: compaction requests fail with websocket: close 1009 (message too big) #4017

Description

@Fwindy

Summary

When Codex (desktop client) uses the WebSocket transport (GET /v1/responseswss://chatgpt.com/backend-api/codex/responses), compaction turns frequently fail. The upstream WebSocket is closed by the server with websocket: close 1009 (message too big), and the downstream client receives a 500 internal_server_error. The session then has to reconnect, and compaction does not complete.

Environment

  • Provider: codex (OAuth), model gpt-5.5
  • Transport: WebSocket (responses_websockets)

Logs

[info ] [codex_websockets_executor.go:1604] codex websockets: upstream disconnected session=aaa auth=bbb url=wss://chatgpt.com/backend-api/codex/responses reason=send_error err=write tcp 127.0.0.1:4868->127.0.0.1:7890: wsasend: An existing connection was forcibly closed by the remote host.
[error] [codex_websockets_executor.go:1510] codex websockets executor: close websocket error: tls: failed to send closeNotify alert (but connection was closed anyway): write tcp 127.0.0.1:4868->127.0.0.1:7890: wsasend: An established connection was aborted by the software in your host machine.
[info ] [codex_websockets_executor.go:1599] codex websockets: upstream connected session=aaa auth=bbb url=wss://chatgpt.com/backend-api/codex/responses
[info ] [openai_responses_websocket.go:222] responses websocket: client connected id=ccc remote=127.0.0.1
[debug] [conductor.go:5688] Use OAuth provider=codex auth_file=bbb for model gpt-5.5
[debug] [codex_websockets_executor.go:397] Executing Codex Websockets stream request with auth ID: bbb, model: gpt-5.5
[debug] [apply.go:233] thinking: original config from request | provider=codex model=gpt-5.5 mode=level budget=0 level=xhigh
[debug] [apply.go:274] thinking: processed config to apply | provider=codex model=gpt-5.5 mode=level budget=0 level=xhigh
[info ] [codex_websockets_executor.go:1599] codex websockets: upstream connected session=ccc auth=bbb url=wss://chatgpt.com/backend-api/codex/responses
[info ] [codex_websockets_executor.go:1604] codex websockets: upstream disconnected session=aaa auth=bbb url=wss://chatgpt.com/backend-api/codex/responses reason=upstream_disconnected err=websocket: close 1009 (message too big)
[info ] [openai_responses_websocket.go:1322] responses websocket: downstream_out id=aaa type=1 event=error payload={"type":"error","status":500,"error":{"message":"websocket: close sent","type":"server_error","code":"internal_server_error"}}
[warn ] [openai_responses_websocket.go:444] responses websocket: forward failed id=aaa error=write tcp 127.0.0.1:8317->127.0.0.1:4867: use of closed network connection
[info ] [openai_responses_websocket.go:266] responses websocket: upstream execution session closed id=aaa
[warn ] [openai_responses_websocket.go:270] responses websocket: close connection error: close tcp 127.0.0.1:8317->127.0.0.1:4867: use of closed network connection
[info ] [gin_logger.go:102] 200 |         47.805s |       127.0.0.1 | GET     "/v1/responses"

Analysis / likely cause

The key line is:

reason=upstream_disconnected err=websocket: close 1009 (message too big)

1009 is a WebSocket protocol close code emitted by the upstream (chatgpt.com / its edge), meaning the message it received exceeded the server's per-message size limit.

A compaction turn replays the entire conversation transcript as a single response.create WebSocket message. Compaction is triggered exactly when the context is at its largest, so this single frame is the worst-case payload and exceeds the upstream per-message limit → upstream closes the socket with 1009.

The other lines are downstream consequences of that teardown, not independent failures:

  • send_error ... forcibly closed — writes to the upstream connection fail after upstream has torn it down.
  • 500 internal_server_error / use of closed network connection — the handler reports the now-closed upstream session to the downstream client.

Additional note: enabling outbound permessage-deflate compression does not help, because the upstream appears to evaluate the decompressed / logical message size, not the on-wire compressed size. (Verified.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions