Host-bound send reports missing AppServerManager after the target processes the message
Version
Codex/AppServer 0.146.0
Impact
A host-bound task send can return:
No AppServerManager registered for hostId
while the exact target nevertheless receives and processes that same message. The sender cannot safely distinguish rejection from delivery-after-error: retrying can duplicate work, while suppressing a retry can lose a genuinely rejected message.
This appears related to, but distinct from, #18556. That issue concerns stale discovered Remote SSH state and startup/reconnect failure. This report concerns truthful send status, host-manager reconciliation, and delivery ambiguity after the effect has occurred.
Minimal natural reproduction
- Resolve an existing task and its current generic remote-control host binding through supported task metadata.
- Send one authorized message once, carrying a unique non-private correlation token.
- Observe the sender returning
No AppServerManager registered for hostId. - Do not retry and do not use a host-omitted fallback.
- Observe through the target's ordinary workflow that it received and processed the same correlation.
- Later metadata may represent the same stable task as
localrather than the earlierremote-controlbinding. - Restarting the daemon did not prevent the false-negative behavior from recurring.
Expected
A send should have exactly one truthful outcome:
- accepted, with a stable delivery/correlation receipt;
- rejected before any delivery effect; or
- explicitly indeterminate when the system cannot prove whether an effect occurred.
Stable task identity and the current actionable AppServerManager binding should reconcile atomically.
Actual
The sender reports that no AppServerManager is registered for the supplied host, but the target processes the message. The same task can later surface with a different generic host binding.
No private task IDs, host IDs, paths, payloads, transcripts, logs, credentials, configuration, network names, or project information are included in this report.
Evidence assessment
Confirmed
- Exact host-bound send returned the error above.
- The intended target processed the same correlation.
- No retry or host-omitted fallback was needed for that processing.
- The behavior persisted after a daemon restart.
- The same stable task later surfaced under a generic
localbinding instead of its prior genericremote-controlbinding.
Leading hypothesis
Host metadata and the actionable AppServerManager registry can become stale or reconcile non-atomically. Delivery may be accepted before the sender receives a manager/status failure.
Alternatives
- Manager/socket lifecycle changes during routing invalidate the response path after enqueue.
- Remote-control enrollment or proxy state disagrees temporarily with task metadata.
General Wi-Fi failure is not evidenced by this reproduction.
Requested product invariants
- A stable task identity resolves atomically to exactly one current actionable AppServerManager, or the operation fails before enqueueing any effect.
- A send never returns a definitive failure after the message may have been accepted or processed.
- Ambiguous outcomes return an explicit indeterminate state with a correlation receipt.
- Caller-supplied idempotency/correlation keys survive routing end-to-end.
- Repeated delivery with the same key cannot process the payload twice.
- Host migration, reconnect, daemon restart, proxy rebinding, and manager replacement invalidate stale bindings deterministically.
- Sender and recipient receipts refer to the same stable task, correlation key, and delivery attempt.
Deterministic regression tests
- Remap a task from remote-control to local between metadata resolution and send; assert atomic rerouting or rejection before enqueue.
- Replace/restart the manager after resolution; assert an old binding cannot produce delivery followed by a definitive failure.
- Simulate successful enqueue followed by response-channel loss; assert an explicit delivery-uncertain result with a receipt.
- Remove the manager before enqueue; assert definitive rejection and zero recipient processing.
- Submit the same correlation after an ambiguous result; assert at-most-once processing.
- Exercise local/remote-control binding transitions and assert stable task identity plus current-manager reconciliation.
- Restart with existing tasks and assert stale registry entries are invalidated.
- Assert every sender outcome matches recipient state: accepted, rejected-before-effect, or explicitly uncertain.
Retry and dedupe safety
Until the product can provide a truthful disposition, callers must treat this error as delivery-uncertain and avoid automatic retry or host-omitted fallback.
1 Comment
Sanitized controlled follow-up (2026-08-05)
This is an interim debugging result, not a claim that the issue is resolved.
Environment:
Plain-language control tests
Two tiny, harmless test messages were used. Each asked the intended recipient to return one fixed, non-private acknowledgement phrase:
These successful controls show that both routes can work. They do not disprove the intermittent bug; they help separate message delivery from the later observation/receipt path.
Reproduced failure in the same Desktop session
wait_threadscapability remained advertised but invocations repeatedly failed with:No handler registered for tool: codex_app.wait_threadsread_threadsucceeded for the same stable task when using its freshly listed binding.local,remote-control, andslingshot; project association was absent on one projection and present on a later one.Current inference ceiling
This does not identify the exact server-side code path. It narrows the live failure to tool-specific handler registration and/or host-binding reconciliation in the Desktop/tool-gateway layer above a healthy local app-server.
It also provides a concrete mechanism for the receipt ambiguity reported here: a target effect can complete successfully while a later observation or receipt capability has no registered handler or resolves a stale binding.
Useful product-side telemetry would be the handler registry and host-binding transition for the advertised tool between capability exposure and invocation.
No private task IDs, host IDs, paths, payloads, transcripts, correlation values, credentials, configuration bodies, or log contents are included. No retry, daemon restart, or configuration change was performed.