Skip to content

fix(core): close websocket after provider error frame - #47973

Merged
nexxeln merged 3 commits into
v2from
websocket-error-close
Sep 9, 2026
Merged

fix(core): close websocket after provider error frame#47973
nexxeln merged 3 commits into
v2from
websocket-error-close

Conversation

@nexxeln

@nexxeln nexxeln commented Sep 8, 2026

Copy link
Copy Markdown
Member

Summary

  • After a Responses WebSocket error frame the transport kept the channel for reuse, so the next exchange could be written to a connection the server had already given up on and fail the step with provider.transport: WebSocket closed with code 1000delivery: ambiguous, which is deliberately never retried. Seen live during a WebSocket soak against a ChatGPT Codex credential.
  • Drop the channel after every error terminal (provider-failure and both rejected recoveries), so the runner's retry or the next step opens a fresh connection. The rotate-and-retry-full special case is subsumed.
  • Add two debug lines needed to verify WebSocket behaviour from logs: session websocket sending … mode=full|incremental and session websocket poisoned … code= active=.

Probed both backends with a raw response.create socket after an error frame (previous_response_not_found and a bad model):

  • api.openai.com keeps the socket open; a follow-up request on it succeeds. Reconnecting after an error costs one handshake there.
  • chatgpt.com/backend-api/codex stops serving the connection after either error: the follow-up request is never answered and the socket dies with 1006 ~2.7 s later. That includes the stale-previous_response_id case, so retry-full on the same socket would have hung and failed the same way.

Groundwork for making the channel the default.

Validation

  • New test: closes the connection after a provider error frame so the next call reconnects; clears a rejected checkpoint before the runner retries full and the live clears a rejected continuation … test now expect the retry on a second connection.
  • session-model-transport, session-checkpoint-transport, session-model-transport-live: 38 passed. Core suite via bun run test: 5,248 passed, 35 skipped. Core typecheck clean.

Follow-up

Codex reports a stale continuation as invalid_request_error with message "Invalid previous_response_id." and no code, so OpenResponsesContinuation never classifies it as retry-full there; the step fails instead of retrying full.

@nexxeln
nexxeln merged commit 3c4c7b4 into v2 Sep 9, 2026
10 checks passed
@nexxeln
nexxeln deleted the websocket-error-close branch September 9, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant