send_message_to_thread reports handler error even when delegation is delivered
Summary
send_message_to_thread can return No handler registered for tool: send_message_to_thread even though the target Codex thread actually receives the message as a codex_delegation and starts processing it.
This makes the sender side think delivery failed when it did not.
Environment
- Codex app: 26.616.81150
- Bundled Codex CLI:
codex-cli 0.142.0 - Surface: Codex desktop app, local thread coordination tools
Observed behavior
When sending follow-up prompts from one Codex thread to other local Codex threads:
- Some calls returned success with a
threadId. - Other calls returned:
No handler registered for tool: send_message_to_thread
However, after calling read_thread on those target threads, the latest target-thread input was present as a codex_delegation with:
- the expected source thread id
- the expected prompt content
- target thread status changing to active / in progress
Example source thread:
019efa60-ec1f-7df2-83f8-117fbaf17288
Affected target examples:
019eb9dc-449d-7ac1-a467-82087206d53c
019eb9dc-6332-79e3-92f8-bc3eefb911e5
019eb494-6e05-7d12-9ae9-753efac95105
019ed108-2f13-7c00-a528-1ad31f99fa7f
019ef324-d21a-7b32-8f3c-4fa1a72895a6
A later read_thread call confirmed the delegation had actually been delivered to each of those threads.
Expected behavior
If delivery succeeds, send_message_to_thread should return success, ideally with a stable delivery receipt or message id.
If the tool cannot determine final delivery state, it should return an explicit unknown / pending delivery state rather than a generic handler error.
If delivery succeeds but an acknowledgement handler fails, the result should distinguish that case, e.g. delivered_but_ack_failed.
Actual behavior
The call returns a handler error that looks like delivery failure, while the target thread actually receives and processes the delegation.
Impact
This breaks multi-thread coordination reliability. An agent may:
- incorrectly mark a message as not delivered
- ask the user to manually forward a message that was already delivered
- retry and create duplicate tasks
- write inaccurate coordination logs
Temporary workaround
After send_message_to_thread reports a handler error, call read_thread on the target thread and verify whether the latest input is a matching codex_delegation with the expected sourceThreadId and content before retrying or marking delivery failed.
Suggested fix
Separate message delivery status from local acknowledgement / handler failure. If a post-delivery acknowledgement handler fails, surface it as an acknowledgement error while preserving a successful delivery result.