Skip to content

Bug: Responses API WebSocket proxy sets previous_response_id=null, breaking multi-turn tool calls (Codex v0.118.0) #2596

@0x43e96f

Description

@0x43e96f

Bug Description

When Codex (v0.118.0+) uses the Responses API via WebSocket through CLIProxyAPI, all multi-turn tool calls fail with:

400: No tool call found for function call output with call_id call_xxx

Root Cause (confirmed via logs)

CLIProxyAPI's WebSocket → HTTP translation does not chain previous_response_id between turns.

From proxy-config.yaml request logs:

Turn 1 (prewarm):  previous_response_id: "resp_prewarm_5c1ef71b-..."  ✅
Turn 2 (actual):   previous_response_id: null                          ❌
Turn 3:            previous_response_id: null                          ❌
Turn 4:            previous_response_id: null                          ❌

What should happen: each turn must reference the response_id returned by the previous turn. OpenAI uses this to look up the tool calls from the previous response. When null is sent, OpenAI starts a fresh conversation with no tool call context → rejects the function_call_output.

Timeline

  • Before Codex v0.118.0: Codex used Chat Completions API (stateless) → round-robin worked fine, no previous_response_id needed
  • After Codex v0.118.0: Codex switched to Responses API over WebSocket (Openai-Beta: responses_websockets=2026-02-06) → stateful, previous_response_id must be chained between turns

Evidence

Log header from Codex request:

Openai-Beta: responses_websockets=2026-02-06
Version: 0.118.0

Log showing null chaining (from v1-responses-*.log):

{"previous_response_id": null, "model": "gpt-5.3-codex", ...}  // turn 2, 3, 4

Error in main.log (source: openai_responses_websocket.go:632):

responses websocket: downstream_out event=error payload={"type":"error","status":400,
"message":"No tool call found for function call output with call_id call_xxx"}

Expected Fix

In openai_responses_websocket.go, when proxying WebSocket → HTTP:

  • Track the response_id returned by each OpenAI HTTP response
  • Use it as previous_response_id in the next HTTP request for the same WebSocket session

Workaround

Remove openai_base_url from Codex config to bypass CLIProxyAPI and connect directly to OpenAI.

Related: #2594 (session-sticky-round-robin feature request)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions