Description
When an OpenAI-compatible streaming provider returns a normalized HTTP 408 before OpenCode has received any semantic response event, OpenCode terminates the turn instead of retrying it. The user must manually resend the prompt.
The affected proxy intentionally normalizes abnormal upstream stream termination as:
HTTP 408
{"type":"error","sequence_number":0,"code":"request_timeout","message":"stream error: stream disconnected before completion: stream closed before response.completed"}
sequence_number: 0 is important: no usable Responses event, text delta, or tool call has reached OpenCode. Retrying at this point should not replay visible output or local tool execution. Retrying after any semantic stream event would be unsafe and is explicitly out of scope.
I manually built CLIProxyAPI with router-for-me/CLIProxyAPI#4580, which fixes one prefix-only SSE bootstrap failure. It noticeably reduced the frequency of these 408s, but did not eliminate them. The remaining normalized 408 still stops the OpenCode turn.
This differs from #30611 and #38683: those cover raw/wrapped transport failures. Here the client receives an API error with HTTP status 408, so the current SessionRetry.retryable() path does not explicitly classify it as retryable (unlike 5xx responses).
Expected behavior
For an OpenAI-compatible streaming request that fails with HTTP 408 / request_timeout before the first semantic event, retry the turn with bounded exponential backoff, then surface the error if the retry budget is exhausted.
Do not retry once OpenCode has received a text delta, a tool call, or another semantic response event.
Suggested coverage
- HTTP 408 before any Responses SSE event retries and a subsequent successful attempt completes.
- HTTP 408 after a text delta does not retry.
- HTTP 408 after a tool-call event does not retry.
- Repeated pre-output 408s stop after a bounded number of attempts.
Environment
Related
Description
When an OpenAI-compatible streaming provider returns a normalized HTTP 408 before OpenCode has received any semantic response event, OpenCode terminates the turn instead of retrying it. The user must manually resend the prompt.
The affected proxy intentionally normalizes abnormal upstream stream termination as:
sequence_number: 0is important: no usable Responses event, text delta, or tool call has reached OpenCode. Retrying at this point should not replay visible output or local tool execution. Retrying after any semantic stream event would be unsafe and is explicitly out of scope.I manually built CLIProxyAPI with router-for-me/CLIProxyAPI#4580, which fixes one prefix-only SSE bootstrap failure. It noticeably reduced the frequency of these 408s, but did not eliminate them. The remaining normalized 408 still stops the OpenCode turn.
This differs from #30611 and #38683: those cover raw/wrapped transport failures. Here the client receives an API error with HTTP status 408, so the current
SessionRetry.retryable()path does not explicitly classify it as retryable (unlike 5xx responses).Expected behavior
For an OpenAI-compatible streaming request that fails with HTTP 408 /
request_timeoutbefore the first semantic event, retry the turn with bounded exponential backoff, then surface the error if the retry budget is exhausted.Do not retry once OpenCode has received a text delta, a tool call, or another semantic response event.
Suggested coverage
Environment
Related