Adom Hydrogen
Public Made by Adomby adom
The whole Adom experience as one signed native app: your editor, your AI agent, and the full electronics design toolchain, running locally on your own machine.
WSL_WEDGED flaps declare/clear every 30s and tells the user to restart Windows - the cosmetic workspace_stats 3s cap feeds the wedged detector
ah 1.0.164 (build c4613fbf5d69aba7824d5992894d59604f6b31ee-dirty) · ab 2.1.8 · Windows 11 10.0.26200.9168 · WSL 2.7.11.0 (kernel 6.18.33.2-2)
What happened
Machine slept. I woke it, clicked Update on Hydrogen's banner, and the update to 1.0.164 installed and relaunched. Immediately after it came back, the "Starting Workspace…" console filled with the full multi-line WSL_WEDGED declared paragraph, repeating on a metronome — declared / forensics / cleared, over and over, with nothing else in the dialog, for the whole life of the session.
At the same time I was restarting my own personal WSL distros (Ubuntu-24.04, with several VS Code WSL windows reconnecting to it). That turns out to be the whole story, and it is the point of this report: an ordinary, transient, user-caused slowdown of wslservice gets escalated into a repeating "restart Windows" banner.
Verbatim, from %APPDATA%\hydrogen-desktop\hydrogen-desktop.log:
10:22:47.858 [wsl] WSL_WEDGED declared: 3 consecutive wsl.exe timeouts (last: workspace_stats probe (3s)). The Windows WSL management plane (wslservice) is not responding; the distro itself may be fine. Suppressing non-essential wsl.exe calls; workspace health falls back to HTTP probes. A Windows restart (or restarting WslService) clears this.
10:22:48.162 [wsl] WSL_WEDGED forensics: 12 wsl.exe processes system-wide
10:22:50.331 [wsl] WSL_WEDGED cleared: wsl.exe is responding again
10:23:18.070 [wsl] WSL_WEDGED declared: 3 consecutive wsl.exe timeouts (last: workspace_stats probe (3s)). ...
10:23:18.304 [wsl] WSL_WEDGED forensics: 12 wsl.exe processes system-wide
10:23:20.400 [wsl] WSL_WEDGED cleared: wsl.exe is responding again
The shape of it
Declared and cleared alternate on an exact 30-second period — the workspace_stats poll interval — and each declaration is cleared ~2 seconds later:
10:21:47.604 declared → 10:21:50.129 cleared (2.5s)
10:22:17.724 declared → 10:22:20.249 cleared (2.5s)
10:22:47.858 declared → 10:22:50.331 cleared (2.5s)
10:23:18.070 declared → 10:23:20.400 cleared (2.3s)
10:23:48.236 declared → 10:23:50.482 cleared (2.2s)
10:24:18.404 declared → 10:24:20.618 cleared (2.2s)
10:24:48.566 declared → 10:24:50.702 cleared (2.1s)
10:25:18.767 declared → 10:25:20.769 cleared (2.0s)
It ran from 10:14:00 until the app exited at 10:25:25 — 11 minutes, 12 declare/clear pairs in that session alone. Across the whole log there are 31 declarations, and 25 of them name workspace_stats probe (3s) as the trigger:
25 last: workspace_stats probe (3s)
5 last: wsl ["-d", "Adom-Workspace", "bash", "-lc", "pgrep -f 'code-server' ..."] (60s)
1 last: wsl ["--status"] (60s)
WSL was never wedged. The 3s-capped stats probe was simply slower than 3s while wslservice was busy with my distro restarts; it tripped the wedged threshold every poll cycle, and the next call with a real budget answered fine and cleared it.
How slow "slow" actually was
Sampled live on the machine while writing this up, wsl.exe --list --verbose — about the cheapest management-plane call there is — timed out at 15 seconds:
Adom-Workspace state:
TIMEOUT
An earlier run of the same command did return, showing Ubuntu-24.04 Running, Adom-Workspace Stopped, docker-desktop Stopped. vmmemWSL was at 5.5 GB.
So a 3-second cap on an in-distro stats read is nowhere near survivable under normal user load. Nothing was broken — wslservice was just busy.
Three defects
1. The workspace_stats 3s cap has two handlers and they disagree. Sixteen minutes earlier in the same log, the identical timeout took the graceful path:
09:58:09.261 [wsl] workspace is healthy (code-server answering); CPU/RAM readout skipped this poll, the in-distro stats read exceeded its 3s cap. Numbers resume when wsl.exe responds.
That is the right behavior — a 3s cap on a cosmetic CPU/RAM readout is a soft budget, not evidence of a management-plane failure. But the same timeout also increments the global consecutive-timeout counter that declares WSL_WEDGED. A best-effort probe should be excluded from the wedged detector entirely, or the detector should only count probes that carry a real (60s) budget.
2. No hysteresis — the state flaps instead of latching or backing off. Declaring and clearing every 30s for 11 minutes is noise, not signal. Something cleared 2s after being declared should never have been declared. Wants a minimum dwell time before declaring, and suppression so a repeat declaration inside N minutes does not re-emit the whole paragraph.
3. The message is a 60-word paragraph that tells the user to restart Windows. Printed 12 times into a startup dialog that had nothing else in it, on a machine where nothing was wrong and the actual cause was the user restarting their own distros. Even with the flapping fixed, this is far too heavy for a console line — a one-line summary with the detail behind a disclosure, and no "restart Windows" advice until the condition has genuinely persisted.
Timeline
10:13:44.978 [wake-heal] detected: wake detected (automatic, slept ~15m33s)
10:13:45.061 [main-watchdog] MAIN THREAD BLOCKED for ~939s ...
10:14:00.484 [wsl] WSL_WEDGED declared: ... (last: workspace_stats probe (3s))
10:14:14.646 Applying staged update 1.0.164 from ...Adom.Hydrogen_1.0.164_x64-setup.exe
10:14:16.496 Spawned relauncher ... exiting so the installer can replace files
=== Hydrogen Desktop started at 2026-09-03 10:14:34 ===
10:15:01.848 [wsl] WSL_WEDGED forensics: 8 wsl.exe processes system-wide
... flap continues every 30s ...
10:25:25.325 [app] Exiting pid=70516 after 650s
The flap starts in the pre-update process right after wake, survives the update and relaunch, and continues in the new 1.0.164 process. So it is not a one-off of a wedged post-wake state, and it is not new in 1.0.164 — but 1.0.164 is where it was seen, and the post-update "Starting Workspace…" dialog is what made it visible.
Note on the forensics: N wsl.exe line — it is misleading
I first read the rising count (4 → 8 → 10 → 12) as Hydrogen leaking probe processes. That was wrong, and the line invites the mistake. Checking parentage of every live wsl.exe:
PID Parent ParentName Cmd
40084 39272 Code wsl.exe -d Ubuntu-24.04 sh -c "$VSCODE_WSL_EXT_LOCATION/scripts/wslSe...
18468 40084 wsl wsl.exe -d Ubuntu-24.04 sh -c "$VSCODE_WSL_EXT_LOCATION/scripts/wslSe...
46296 39272 Code wsl.exe -d Ubuntu-24.04 -e /home/<user>/.vscode-server/bin/110a328ea54b4...
40924 46296 wsl wsl.exe -d Ubuntu-24.04 -e /home/<user>/.vscode-server/bin/110a328ea54b4...
... (10 total, all parent=Code, all -d Ubuntu-24.04) ...
26824 16968 hydrogen wsl -d Adom-Workspace -u root -- bash -lc "systemctl restart adom-relay.service ...
57216 26824 wsl wsl -d Adom-Workspace -u root -- bash -lc "systemctl restart adom-relay.service ...
Every accumulating process belongs to VS Code, attached to my personal Ubuntu-24.04 — including a pair 10 days old. Hydrogen's own contribution was a single transient pair against Adom-Workspace, which reaped normally by the next sample.
That is not a Hydrogen bug, but it is a diagnostics bug: forensics: 12 wsl.exe processes system-wide is a system-wide count printed inside a Hydrogen-blames-WSL message, so it reads as Hydrogen's own process leak to anyone triaging it (it fooled me for a while). Suggest either splitting it into own-vs-other (3 spawned by us, 9 by other processes) or naming the top parent process — which would also have put the actual cause, VS Code hammering wslservice, right on the line.
Expected
Starting Workspace… shows workspace startup progress. A slow cosmetic stats read is skipped quietly (as the 09:58 line already does), does not declare a management-plane failure, does not flap every 30 seconds, and does not tell the user to restart Windows because another app was busy with WSL.
Full log excerpt attached.
Possibly related: adom/hydrogen#26 (false-negative health probe forcing code-server restarts while code-server is actually up) — same family of "a probe's timeout is read as a failure of the thing being probed."