Skip to content

fix(proxy): recover anchored HTTP bridge turns after silent response.create #1735

Description

@kevinsslin

Pre-flight

Summary

An HTTP Responses bridge continuation can still fail closed after the upstream accepts response.create but emits no response.created. The eventless watchdog invokes the pre-created retry path, but the existing replay safety predicate rejects a request that already carries previous_response_id even when there has been zero upstream response event, model output, or downstream-visible output.

The client then receives the terminal 502 upstream_request_timeout and spends its own reconnect budget. In Codex Desktop this presents as the task becoming paused instead of the bridge making one bounded server-side recovery attempt.

This remains observable after upgrading to stable 1.23.0. The production symptom is:

Upstream did not acknowledge response.create before the client-safe deadline
missing_response_created_timeout

Expected behavior

For a hard bridge owner, if the request is still pre-response.created and has no response ID, response event, model output, downstream sequence, downstream-visible output, or account-scoped file requirement, codex-lb should:

  1. reconnect on the same account;
  2. resend the unchanged previous_response_id-anchored request once;
  3. complete the original downstream request if the replacement socket acknowledges it; and
  4. fail closed after that one bounded attempt if the replacement is also silent.

Soft affinity, file-pinned requests, any observed output/event, and subsequent retries must retain the existing fail-closed behavior. No indefinite recovery or new setting is proposed.

Reproduction

  1. Use a hard HTTP bridge session.
  2. Complete one response to establish previous_response_id.
  3. Send a continuation carrying that anchor.
  4. Make the upstream socket accept the request but remain silent before response.created.
  5. Wait for the eventless watchdog.
  6. Observe no same-anchor replacement send and a terminal 502 upstream_request_timeout.

Acceptance criteria

  • A route-level regression proves a silent hard continuation recovers on a replacement socket.
  • A second silent replacement is not retried indefinitely.
  • Account ownership, durable operation fencing, admission, reservation settlement, and file ownership remain unchanged.
  • The fix is zero-config and does not alter direct WebSocket behavior.

Related: #1393, #1394, #1711, #1723.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions