Skip to content

fix(desktop): avoid double-quoting the SSH update mutex path on remote hosts - #99189

Closed
twotnguyen wants to merge 1 commit into
NousResearch:mainfrom
twotnguyen:fix/desktop-ssh-update-mutex-path
Closed

fix(desktop): avoid double-quoting the SSH update mutex path on remote hosts#99189
twotnguyen wants to merge 1 commit into
NousResearch:mainfrom
twotnguyen:fix/desktop-ssh-update-mutex-path

Conversation

@twotnguyen

Copy link
Copy Markdown
Contributor

Summary

When connecting to a remote host over SSH, withRemoteUpdateMutex wrapped mutexPath in shq() even though mutexPath was already the output of expandRemotePath() (which already produces a shell-quoted string or "$HOME"'/…' fragment).

On remote Linux hosts, the extra shq() passed literal single-quote characters inside sys.argv[1] to the Python mutex helper. When Python evaluated os.path.dirname(sys.argv[1]) on a path like '/home/hermes/.hermes/…', it treated the path as relative because it began with ' instead of /. Calling os.makedirs(parent, exist_ok=True) then created a literal directory named ' under the user's home directory (e.g. /home/hermes/').

Changes

  • In apps/desktop/electron/remote-lifecycle.ts, embed mutexPath directly into withRemoteUpdateMutex's command string instead of wrapping it in shq(mutexPath).
  • In apps/desktop/electron/remote-lifecycle.test.ts, add regression test buildSpawnCommand does not double-quote the update mutex path asserting that both absolute and tilde hermesHome paths produce clean python3 -c ... <path> arguments without double-quoting or literal single quotes.

Fixes #99133

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/desktop Electron desktop app (apps/desktop/*) backend/ssh SSH remote execution sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 31, 2026
@bmgskr2025

Copy link
Copy Markdown

Thanks!

…e hosts

withRemoteUpdateMutex wrapped mutexPath in shq() even though mutexPath is already the output of expandRemotePath() (a shell-quoted string or $HOME fragment). On remote Linux hosts, this passed literal single-quote characters in sys.argv[1], causing Python's os.path.dirname() to treat the path as relative and create a literal ' directory under $HOME.

Embed mutexPath directly into the command string so $HOME expands and quote characters are not duplicated, matching the pattern used by other expandRemotePath call sites.

Fixes NousResearch#99133
@SZWzz

SZWzz commented Sep 4, 2026

Copy link
Copy Markdown

Heads-up on overlap: this fixes the same withRemoteUpdateMutex double-quoting site as #96260 (and #96187).

Whichever one lands fixes the quoting fault, so no argument from me either way — but for whoever reviews: #96260 covers this same one-line mutex change plus two adjacent correctness defects in the same spawn chain that the one-line fix alone leaves behind:

  • the published lockfile pid is a JSON string ("__PID__" substituted unquoted), while readLockfile requires an integer and the reuse regex only matches "pid":<digits> — so every fresh spawn's ownership record is malformed;
  • the detached setsid/nohup shell echoed $! from both the inner and outer shells, so $child captured a two-line value and the sed substitution was invalid under POSIX sh (now guarded: non-integer $child fails closed with exit 76).

It also pins the contract with argv-level regression tests (asserting the exact argv the remote python receives, under dash), which is the gap that let this site regress silently in the first place — the existing cmd.includes(...) assertions pass under both the broken and fixed forms.

Happy to rebase/adjust if a maintainer prefers to land a minimal one first.

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Thanks @twotnguyen — this is the right fix for the right line (#99133's root cause), and it was verified live: the composed spawn command run through a real sh hands python sys.argv[1]="'/home/hermes/.hermes/.hermes-update-in-progress.mutex'" on origin/main, and the clean path once shq() is dropped.

Closing in favour of #104206, which carries the same one-line change from #96187 (@koltyj, filed 27 Aug — earliest of the three PRs on this site) with cherry-pick authorship, plus its test that parses the command with a real sh rather than regex-matching the string. SZWzz's overlap note above is correct: whichever lands fixes the fault; first-filer gets the credit. Your report and analysis are referenced in the PR body. If #104206 fails to land for any reason this reopens.

kshitijk4poor pushed a commit that referenced this pull request Sep 6, 2026
`apps/desktop/'` is not a real path. It is a literal single-quote directory
holding a full absolute path as nested subdirectories:

    apps/desktop/'/var/folders/5h/.../hermes-update-mutex-LMF9y5/home/.hermes-update-in-progress.mutex'

Both files are 0 bytes, nothing in the tree references them, and the leading
and trailing `'` are part of the filenames. They are the fingerprint of the
double-quoted mutex path in `withRemoteUpdateMutex()`: the path reaches Python
with its shell quotes still attached, so it is treated as CWD-relative and
`os.makedirs()` materialises the whole absolute path under whatever directory
the process happened to be in. Running
`apps/desktop/electron/remote-lifecycle.test.ts` from `apps/desktop`
reproduces it on the spot.

They were swept in by a `git add .` in 3662057, an unrelated menu-label
commit.

This only removes the committed artifact. The generator is a separate concern
already covered by open PRs (#99189, #96187, #96260) and issues (#99133,
#96212, #96188); those repair the quoting but none of them deletes these two
files, so the litter would survive whichever one lands.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/ssh SSH remote execution comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop SSH creates a quote-prefixed update mutex path on remote Linux hosts

5 participants