Summary
When Claude Code (2.1.268) believes it is talking to api.anthropic.com (e.g. behind a hosts-file loopback mapping used for Remote Control), it enables the message-threads-2026-08-12 beta and, after the first request of a turn, sends only the new messages with thread: {"type":"continue","previous_message_id":"msg_…"}. The proxy forwards that to Codex as if it were a full conversation.
Results: No tool call found for function call output with call_id call_… 400s from Codex when the continuation carries a tool_result (≈820 on this machine in two days across gpt-5.6-luna/sol/terra and gpt-6-astra), and silent context loss when it carries a plain user message (Codex answers with only that message plus the system prompt).
Suggested handling
Claude Code drops threading for the session and retries with a full-history thread:{type:"create"} when it receives a 400 whose message contains capability_rejected: beta_header:message-threads-2026-08-12. The proxy could reject thread.type === "continue" (or any thread field) with exactly that message instead of forwarding a partial conversation. A create carries the whole history and can be forwarded after dropping the field.
Proxy 0.1.38, Linux. Client-side traces of the create/continue bodies available on request. Gateway-side counterpart: Eigenwise/eigenwise-toolshed#58
Summary
When Claude Code (2.1.268) believes it is talking to
api.anthropic.com(e.g. behind a hosts-file loopback mapping used for Remote Control), it enables themessage-threads-2026-08-12beta and, after the first request of a turn, sends only the new messages withthread: {"type":"continue","previous_message_id":"msg_…"}. The proxy forwards that to Codex as if it were a full conversation.Results:
No tool call found for function call output with call_id call_…400s from Codex when the continuation carries atool_result(≈820 on this machine in two days across gpt-5.6-luna/sol/terra and gpt-6-astra), and silent context loss when it carries a plain user message (Codex answers with only that message plus the system prompt).Suggested handling
Claude Code drops threading for the session and retries with a full-history
thread:{type:"create"}when it receives a 400 whose message containscapability_rejected: beta_header:message-threads-2026-08-12. The proxy could rejectthread.type === "continue"(or anythreadfield) with exactly that message instead of forwarding a partial conversation. Acreatecarries the whole history and can be forwarded after dropping the field.Proxy 0.1.38, Linux. Client-side traces of the
create/continuebodies available on request. Gateway-side counterpart: Eigenwise/eigenwise-toolshed#58