Skip to content

fix(server): pin background service to a stable Node path - #1

Draft
cestercian wants to merge 414 commits into
mainfrom
cursor/macos-service-stable-node-path-9093
Draft

cestercian wants to merge 414 commits into
mainfrom
cursor/macos-service-stable-node-path-9093

Conversation

@cestercian

@cestercian cestercian commented Sep 10, 2026 •

Copy link
Copy Markdown
Owner

What Changed

t3 service install / update now persist a durable absolute Node path in launchd and systemd units instead of Homebrew's versioned Cellar realpath. The service launcher uses the same path when handing off managed runtimes, so a later brew upgrade node does not leave ProgramArguments[0] / ExecStart pointing at a deleted keg.

Keg-only node@* formulas rewrite to $prefix/opt/node@N/bin/node rather than $prefix/bin/node. process.argv0 is kept only when it is an absolute non-keg path that resolves to the same executable as execPath.

Why

Homebrew's /opt/homebrew/bin/node is a symlink. Node realpaths process.execPath to /opt/homebrew/Cellar/node/<version>/bin/node. That keg disappears on upgrade even though the prefix shim still works. The renderer already requires an absolute Node (no PATH lookup); the bug was pinning the keg realpath.

node@22 is keg-only, so $prefix/bin/node can be missing or a different major. exec -a can make argv0 a path that does not exist, so it is not trusted without a realpath/inode check.

Fixes pingdotgg#11054

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes
Open in Web Open in Cursor 

shivamhwp and others added 30 commits September 14, 2026 12:39
…1407)

Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…de_modules (pingdotgg#11750)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…og (pingdotgg#11753)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… only (pingdotgg#11770)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…e palette open (pingdotgg#11762)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… on the clone (pingdotgg#11774)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…1765)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…nect login (pingdotgg#11794)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…ingdotgg#11811)

Co-authored-by: Bil0000 <bilal.bakr.elsherif@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…rets (pingdotgg#11760)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
yordis and others added 24 commits September 18, 2026 15:55
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…7861)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…exists (pingdotgg#12540)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
)

Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Homebrew Node realpaths process.execPath into a Cellar keg that brew
upgrade deletes. Persist the prefix shim in launchd/systemd units and
spawn managed runtimes through the same durable path.
Versioned node@ formulas are keg-only, so rewriting Cellar execPath to
$prefix/bin/node can pick a different major. Persist
$prefix/opt/node@N/bin/node instead, and ignore argv0 unless it resolves
to the same executable as execPath.
Keg-only node@ Cellar paths already rewrite to $prefix/opt/node@N/bin.
Do not put an exec -a alias such as /tmp/not-node on the service PATH;
prefer host.execPath unless argv0 resolves to the same Node binary.
@cursor
cursor Bot force-pushed the cursor/macos-service-stable-node-path-9093 branch from cebee96 to 7b286d3 Compare September 19, 2026 11:39
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Sep 19, 2026
systemd units do not embed PATH. Check the launchd plist so a Cellar
linuxbrew execPath still contributes $prefix/bin, not the keg.
launchd already received the durable host-Node directory. systemd
ignored environmentPath, so Linuxbrew Cellar rewrites never reached
the unit. Emit Environment=PATH=... and compare argv0 identity with
bigint stats so large inodes cannot collide.
@github-actions

Copy link
Copy Markdown

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for 3f114af.

This comment will update automatically after the next completed run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: macOS service pins Homebrew Node Cellar path, making Node upgrades unsafe