This document explains adapter log events that are useful when Codex tool-result continuation, upstream calls, or streaming responses fail.
$env:RUST_LOG = "codex_opencode_adapter=debug"
cargo run --releaseThe default tracing filter is codex_opencode_adapter=info.
These events are emitted around Codex tool-result continuation and stored state replay.
| Event | Level | Location | Meaning |
|---|---|---|---|
stored_response_not_found |
warn | StateStore::get |
A requested previous_response_id was not found in non-expired state. The log includes response_id and TTL cutoff. |
tool_history_unique_fallback_hit |
debug | StateStore::find_by_call_ids |
No previous_response_id was available, but the adapter restored continuation via a unique pending call_id match. The log includes the restored response_id, requested call IDs, and stored pending call IDs. |
tool_history_call_id_ambiguous |
warn | StateStore::find_by_call_ids |
The same requested call_id matched multiple stored responses. The adapter refuses fallback to avoid linking output to the wrong response. |
tool_history_response_ambiguous |
warn | StateStore::find_by_call_ids |
The requested call-id set matched multiple stored responses. The adapter refuses fallback to avoid ambiguous recovery. |
tool_history_call_id_not_found |
warn | StateStore::find_by_call_ids |
The adapter could not restore continuation via pending call_id fallback. The log includes requested and matched call-id counts. |
stateless_tool_history_bypass_state_lookup |
debug | conversion::function_output_call_ids |
Responses input already contains matching tool calls for every tool output, so the server bypasses stored-state lookup and allows stateless history repair. |
Recommended interpretation order:
stored_response_not_found: Codex suppliedprevious_response_id, but the adapter state DB no longer contains it. Check state DB path, TTL, and whether the adapter process changed.tool_history_unique_fallback_hit: Codex omitted or rewroteprevious_response_id, but recovery succeeded through uniquecall_idfallback.tool_history_call_id_ambiguousortool_history_response_ambiguous: recovery was refused because multiple stored responses could match.stateless_tool_history_bypass_state_lookup: Codex sent a self-contained history. Recovery should continue through stateless repair.
Current /v1/responses non-stream upstream HTTP errors return a Responses body with:
status = failed
error.type = upstream_error
error.code = upstream_error
The adapter currently preserves the upstream HTTP status. Real Codex validation must confirm whether non-2xx HTTP status breaks subagent control flow. If it does, only /v1/responses upstream failures should be changed to HTTP 200 with response.status = failed.
The adapter has separate downstream and upstream timeout behavior:
- downstream Responses SSE emits
: keep-alivecomments every 15 seconds while idle; - generated Codex provider configuration uses
stream_idle_timeout_ms = 360000; - non-stream upstream calls use
CODEX_OPENCODE_TIMEOUT_SECONDSas a total request deadline; - stream upstream calls use the same value as connect and per-read timeouts, without a total stream-duration deadline.
A healthy stream may therefore run longer than 300 seconds when upstream chunks continue arriving. The stream should fail when no upstream body bytes arrive for the configured per-read timeout, even though downstream keep-alive comments may still have kept the Codex-facing connection active before that failure.
Existing ~/.codex/config.toml files may still contain the old stream_idle_timeout_ms = 120000. Rerun init or update the provider value manually before treating a 120-second Codex disconnect as an adapter regression.
See STREAMING_TIMEOUTS.md for the complete timeout model and troubleshooting checklist.
Known text-only models are guarded before upstream dispatch. When media input is present, the expected Responses failure is:
status = failed
error.code = unsupported_multimodal_input
For streaming requests, the expected terminal sequence is:
response.created
response.in_progress
response.failed
[DONE]
Unknown model capabilities are passed through to OpenCode Go. If the upstream returns a known multimodal unsupported error, the adapter translates it into the same Responses-level failure.
For a healthy stream, the expected terminal shape is:
response.completed
[DONE]
If the upstream ends before a normal finish reason, record:
- last upstream chunk
- last emitted Responses event
- whether
response.incompleteorresponse.failedwas emitted - whether tool-call adoption had already started
- whether text was buffered because tools were enabled
- effective
stream_idle_timeout_ms - effective
CODEX_OPENCODE_TIMEOUT_SECONDS - whether downstream
: keep-alivecomments continued to arrive
Add a regression test before patching any newly observed stream terminal shape.