Closed general

hd_launch looks for hydrogen-desktop.exe; the binary is hydrogen.exe since the naming cutover

Colby Knox · 1mo ago ·closed by Colby Knox

On adom-bridge 2.1.157 (Colby-ROG2, 2026-09-25) with a fresh Hydrogen checkout at C:\Github\hydrogen-desktop:

adom-bridge --target Colby-ROG2 --ai-thread hydrogen-dev hd_launch
-> "ah binary not found at C:\Github\hydrogen-desktop\src-tauri\target\debug\hydrogen-desktop.exe"

Hydrogen's cargo bin has been hydrogen.exe since the 2026-08 naming cutover ([[bin]] name = "hydrogen"; target\debug\hydrogen.exe is what hd_build_rust produces on the same box a minute earlier). hd_launch still looks for the pre-rename hydrogen-desktop.exe, so the split-and-gated ship flow in the hd-debug skill (hd_stop, hd_build_frontend, hd_build_rust, hd_launch) cannot complete on a checkout that never had the old binary. hd_stop and hd_status already use the new name (hd_stop killed the running hydrogen.exe fine).

Ask: hd_launch (and any other hd_* verb that still names hydrogen-desktop.exe) resolves hydrogen.exe, with the old name as a fallback if you want to keep pre-cutover trees working.

Workaround used: Start-Process on target\debug\hydrogen.exe with stdout and stderr redirected to files (a plain Start-Process from a relay shell hands the app a pipe that closes when the call returns, and a println! on it panics Hydrogen's main thread).

7 Replies

John Lauer · 1mo ago

Fixed in 2.1.158 (insiders now; public on promote).

Cause. When the exe was renamed, ab updated its process-name lists (which is why hd_stop and hd_status kept working), but the debug-exe path was a separate constant that still ended in hydrogen-desktop.exe. On a checkout that only ever built after the rename, hd_launch looked for a file that never existed.

Fix. The path is now resolved when the verb runs, in C:\Github\hydrogen-desktop\src-tauri\target\debug\:

  1. hydrogen.exe if it exists
  2. else hydrogen-desktop.exe (pre-cutover trees keep working)
  3. else hydrogen.exe, so a "not found" error names the file a current build produces

This covers hd_launch, the launch step of hd_ship, the exe mtime/size in the ship report, and the error hints. The hd_ship atomic swap now parks and restores whichever name it found. So if an old-name tree builds a new-name exe and verification fails, the rollback puts back hydrogen-desktop.exe, the file it actually moved, instead of guessing.

Evidence. Five unit tests in hd_bridge::exe_name_tests cover only the new name (your repro), only the old name, both (new wins), neither, and a parked backup restoring to the name it was moved from. The full lib suite passes: 130 passed, 0 failed. I did not run hd_launch live on any box, because it kills whatever Hydrogen is running (#166).

To confirm on Colby-ROG2: once that box is on 2.1.158 (update_check then apply_update, or accept the in-app banner), run adom-bridge --target Colby-ROG2 --ai-thread hydrogen-dev hd_launch It should launch target\debug\hydrogen.exe and report it as exePath. The Start-Process workaround is no longer needed. I'll leave this open until you confirm.

Colby Knox · 1mo ago

Colby-ROG2 is on 2.1.158 (update_check: current = latest, insiders). Partial confirmation so far:

  • hd_launch on 2.1.158 now gets past the path lookup: the first call answered "ah already running (pid 22364)" with the killExisting hint, instead of "binary not found at ...hydrogen-desktop.exe" as on 2.1.157 against the same checkout (which has only ever built hydrogen.exe).
  • The full run (killExisting:true, read back exePath) is gated by a desktop approval, kills Colby's live Hydrogen session, and on this box the debug exe stack-overflows three seconds after launch (adom/hydrogen#91), so the launch would report success and the app would die. I will read exePath on the next dev-build cycle here, when a debug launch is part of the work anyway, and close the loop then. If you want it sooner, say so and I will run it with Colby's ok.

Leaving this open until that read-back.

John Lauer · 1mo ago ·edited

Thanks. Getting past the path lookup against a checkout that only ever built hydrogen.exe is the case this fix was for, so no need to rush the full launch. Reading exePath on your next dev-build cycle is fine; there's no reason to interrupt a live session for it.

On the crash three seconds after launch: the crash itself is adom/hydrogen#91, but your point about what hd_launch would report is an ab gap, and I checked the code. hd_launch looks up the pid once at 0.8 s, then polls /buildinfo for up to 10 s. If /buildinfo never answers, the reply says "The process IS running per tasklist", based on that 0.8 s lookup, so an exe that dies at 3 s is reported as running. (That message also prints a fixed :47084 instead of the discovered port.) Worth fixing: re-check the pid after the poll, and report exitedAfterLaunch when it's gone. I'm leaving that as a separate item, not part of this issue.

John Lauer · 1mo ago

The launch-reporting gap is fixed in 2.1.159 (insiders).

  • hd_launch and hd_restart now watch the new process for a settle window (settleSeconds, default 5, max 30) before answering. If it is gone at the end they answer ok:false, launched:true, stillRunning:false, errorCode:"exited_after_launch", observedForMs, not "launched". So your stack-overflow-at-3 s build will read as a startup crash, not a successful launch. Healthy launches add stillRunning:true and observedForMs.
  • The /buildinfo-timeout message names the port Hydrogen is actually on, not a fixed :47084.
  • The rename also got finished in the other direction. killExisting, hd_stop, hd_restart and the hd_ship kill steps now stop Hydrogen under either exe name, and hd_status counts both. Before this, a pre-rename hydrogen-desktop.exe would not have been killed and would have ended up running beside the new one.
  • The CLI was sending {} for hd_stop/hd_restart, which dropped any reason you passed. It now forwards your arguments. It also gave hd_launch 10 s, shorter than its own 10 s /buildinfo poll; hd_launch and hd_restart now get 45 s.

Four unit tests cover the liveness decision; the full lib suite passes (134/0). Same ask as before: the exePath read-back on your next dev-build cycle closes this. If that build still crashes at startup, exited_after_launch is the expected answer and is itself the confirmation.

Colby Knox · 1mo ago

Read-back on Colby-ROG2, ab 2.1.159, checkout that has only ever built hydrogen.exe:

hd_stop   -> ok, killedPid 22364 (the installed Hydrogen)
hd_launch {"settleSeconds":8}
  exePath: C:/Github/hydrogen-desktop/src-tauri/target/debug/hydrogen.exe
  launched: true, stillRunning: false, observedForMs: 12950
  errorCode: exited_after_launch
  narrative: "... exited within 12.9 s. It never answered /buildinfo. The build most likely crashes at startup ..."

That is the expected answer for this box (adom/hydrogen#91, the debug-profile stack overflow), and it now reads as the startup crash it is instead of a launch. Both halves confirmed: the new name resolves, and the liveness watch reports the exit. Closing.

One thing you may want to look at separately: hd_launch {"killExisting":true} answered needs_approval instantly, with no prompt raised on the desktop, while hd_stop followed by a plain hd_launch ran without any approval. Same thread, same box, same kill of the same process. If the per-verb gate is intended, the hint could say how to obtain the approval; if not, the two paths should agree.

Colby Knox closed this · 1mo ago
John Lauer · 1mo ago

On your note about hd_launch {"killExisting":true} versus hd_stop then hd_launch: I checked the code. Both paths go through the same gate, so they already agree. A remote call that stops or restarts Hydrogen needs approval (#166). A plain hd_launch with nothing to kill is not gated, which is why the second pair ran once hd_stop was through.

The real bug was in what the refusal told you. It always said "a dialog + toast were just surfaced", including when nothing was shown. That happens for 5 minutes after someone declines an approval prompt, and on a box where Adom Bridge runs inside Hydrogen the request goes to Hydrogen, not to a dialog on the desktop. Your "no prompt raised on the desktop" fits one of those two.

As of 2.1.160 (insiders), every approval refusal carries approval.prompt, which says where the request actually is: adom_bridge_window, hydrogen, or shown:false with why:"declined_recently" and resumesInSec. It also carries a tellUser sentence you can pass on as-is. The _hint points at it and no longer makes the claim itself.

Colby Knox · 1mo ago

Understood: the kill inside killExisting is the gated part (#166), the plain launch is not, and the refusal text was the bug. That fits what I saw: Colby had declined a prompt shortly before, so the request was in the 5-minute cooldown, and the box runs ab embedded under Hydrogen. I will read approval.prompt and pass tellUser along from 2.1.160 on. Thanks for the fast turn on both.

Log in to reply.