Adom Bridge
Public Made by Adomby adom
Adom Bridge unleashes your AI onto your full PC: full power, full safety. The AI breaks out of the container it runs in and onto your real machine, managing and running your entire laptop as you: launch apps, move files, drive any window, control KiCad, Fusion 360 or your real signed-in browser. Works with any AI, cloud or local (Claude Desktop, Claude Code, Codex), no Hydrogen required. Bridge and its bridges are an operating system for AI, with managed Node and Python runtimes, and a human-onl
Slow bridge /health is reported as a failed spawn, then locked in backoff with no clear cause
ab 2.0.84 · adom/core 4.13.14 · rustdesk bridge 0.3.2 (at time of failure) · Windows 11 Home build 26200 · Python 3.14.0
Summary
A bridge whose health endpoint is merely SLOW is treated as a failed spawn, and after enough retries the bridge is locked into spawn-backoff with no way to run any of its verbs. The surfaced error names the symptom ("did not respond") but nothing tells the caller that a health-check TIMEOUT was the cause, so it reads like a crashed or broken bridge.
This cost a long debugging session on a real user-facing outage (RustDesk remote access was unusable). The bridge process was healthy the whole time; it just answered /health too slowly.
What happened
rustdesk_connect and every other rustdesk_* verb failed with:
Failed to spawn bridge 'rustdesk': bridge 'rustdesk' is backing off after 16 failed spawn attempt(s): bridge 'rustdesk' did not respond on http://127.0.0.1:557...
The bridge's own log showed ab hanging up mid-response:
File "...\bridges-cache\rustdesk\server.py", line 368, in do_GET
self._send(200, status_payload())
File "...\bridges-cache\rustdesk\server.py", line 361, in _send
self.wfile.write(body)
File "C:\Python314\Lib\socketserver.py", line 845, in write
self._sock.sendall(b)
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
Root cause (in the bridge, now fixed in rustdesk-bridge 0.3.4): its status_payload() shelled out to tasklist /V on every /health poll. Measured on this machine:
tasklist_V_ms=2957
tasklist_noV_ms=3556
~3s per health call, which exceeded ab's spawn health-check timeout. ab aborted the connection, counted the spawn as failed, retried, and after 16-17 attempts entered backoff.
Proof it was only latency, never a broken bridge: run by hand, the exact same server.py starts and serves fine ->
rustdesk bridge v0.3.2 listening on 127.0.0.1:59999 (idle-disconnect 3600s)
After caching the session list on a background thread (rustdesk-bridge 0.3.4), the same endpoint answers in 22-74ms and ab spawns it first try.
What I expected
That a slow-but-alive bridge is distinguishable from a dead one, and that the error tells me which one I have.
Suggestions (any one of these would have saved the session)
- Name the timeout in the error. "did not respond" should say "did not respond within Ns (health-check timeout)" and report the measured latency. Right now the caller cannot tell "timed out" from "crashed" from "wrong port".
- Log slow health responses as a warning before failing. If
/healthanswers but takes > ~1s, emit a warning naming the bridge and the latency. That single line would have pointed straight at the cause. - Do not count a TIMEOUT toward permanent backoff the same way a crash does, or make backoff clearable without restarting ab. Today the only recovery I found was restarting Adom Bridge entirely;
bridge_killreturnederrorandrefresh_bridges/rustdesk_readinessjust timed out, because everything routes through the wedged spawn path. - Surface the health-check budget in the SDK docs so bridge authors know the ceiling they must stay under. The bridge SDK says the health endpoint should be cheap, but not what "cheap" means numerically.
Note
The bridge-side bug is already fixed and published (adom/rustdesk-bridge 0.3.4). This issue is only about ab's diagnosability and backoff recovery, which would help any bridge author who trips the same wire.