remote-control relay connection silently disconnects after 20–55 minutes without auto-reconnect (WSL2)
Environment
┌─────────────────────┬────────────────────────────────────────────────────────────────────┐
│ Item │ Detail │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Codex CLI version │ 0.137.0 │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ app-server version │ 0.137.0 │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ OS │ Ubuntu 20.04 on WSL2 (Windows 11) │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ WSL networking mode │ NAT (default) │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ mobile client │ ChatGPT Android app (Codex remote-control) │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Daemon mode │ codex app-server daemon bootstrap --remote-control │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ TCP keepalive │ net.ipv4.tcp_keepalive_time=60, intvl=10, probes=6 (already tuned) │
└─────────────────────┴────────────────────────────────────────────────────────────────────┘
Steps to reproduce
- Start app-server daemon with remote-control: codex remote-control start
- In ChatGPT Android app, connect to the WSL2 Codex environment → works immediately
- Wait 20–55 minutes without any interaction
- Try to access Codex from ChatGPT app again → cannot connect, environment shows as unavailable
Current behavior
The remote-control relay connection dies silently. After disconnection:
- codex app-server daemon version → reports {"status":"running"} (daemon thinks everything is fine)
- ps aux → app-server process still running (same PID)
- remoteControl/status/read API via Unix socket → NO_RESPONSE (socket accepts connection but sends no
data)
- app-server.stderr.log → completely empty in some cases; in other cases shows:
rmcp::transport::worker worker quit with fatal: Transport channel closed,
when Client(HttpRequest("http/request failed: error sending request for url
(https://chatgpt.com/backend-api/wham/apps)"))
- The relay connection never auto-recovers until a full codex remote-control stop && codex
remote-control start is performed
Two distinct failure modes observed
Mode A — Fatal error (with logs):
Stderr shows rmcp::transport::worker fatal exit with Transport channel closed when the HTTP request to
chatgpt.com/backend-api/wham/apps fails. The relay worker crashes but the app-server process stays
alive, leaving the Unix socket in a zombie state.
Mode B — Silent disconnect (no logs):
No errors in app-server.stderr.log at all. ss -tnp shows the only TCP connection is 127.0.0.1 →
127.0.0.1:7090 (internal proxy), with zero outbound connections to chatgpt.com. The upstream relay
connection has been dropped without any logging.
Pattern observed over 6 days (login-start.log)
Every single day required a fresh daemon restart to recover — the relay never auto-recovered on its
own:
2026-05-31: timedOut=true → restart → connected
2026-06-01: timedOut=true → restart → connected
2026-06-02: timedOut=true → restart → connected
2026-06-03: timedOut=true → restart → connected
2026-06-04: timedOut=true → restart → connected
2026-06-05: timedOut=true → restart → connected
2026-06-06: timedOut=true → restart → connected (then disconnected again after ~55 min)
Expected behavior
- The relay connection should auto-reconnect when the upstream connection to
chatgpt.com/backend-api/wham/apps is lost
- Silent disconnections (Mode B) should produce diagnostic logs so the failure reason is traceable
- The remoteControl/status/read API should reflect the actual connection state rather than returning
no response when the relay subsystem is dead
- The daemon health check should detect when the relay worker has exited and restart it
Additional context
- chatgpt.com is reachable from WSL2 (curl gets HTTP 405, ~0.8s latency)
- WSL2 DNS errors (getaddrinfo() failed: -5) appear in dmesg occasionally but do not correlate with all
disconnections — the most recent disconnect happened with no DNS errors present
- This is NOT a WSL2 TCP keepalive issue — keepalive is already configured and the failure is at the
application layer (relay worker exits / upstream connection drops silently)
---
Labels: bug, app, cli
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗