Skip to content

fix(shared): read the Machine and User registry PATH scopes on Windows - #7407

Closed
hey-jj wants to merge 1 commit into
pingdotgg:mainfrom
hey-jj:fix/windows-registry-path-scopes
Closed

fix(shared): read the Machine and User registry PATH scopes on Windows#7407
hey-jj wants to merge 1 commit into
pingdotgg:mainfrom
hey-jj:fix/windows-registry-path-scopes

Conversation

@hey-jj

@hey-jj hey-jj commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

TITLE: fix(shared): read the Machine and User registry PATH scopes on Windows

Fixes #7406.

When the app launches with a stale Windows environment, for example after Node was installed later in the same desktop session, the Windows PATH repair never finds the registered Node directory and the one-click provider update dies with NotFound: ChildProcess.spawn. The repair probes PowerShell with an unscoped [Environment]::GetEnvironmentVariable('PATH'), which returns the PATH the probe inherited from the app itself, while the directory it needs sits in the Machine or User registry scope that the probe never reads.

What changed

buildWindowsEnvironmentCaptureCommand now reads the Machine and User registry scopes for PATH alongside the existing unscoped read and joins the non-empty values, process value first. Every other captured name keeps the single unscoped read. The new test pins the exact generated statement sequence for the PATH capture and pins that FNM_DIR keeps its unscoped read.

Why this shape

The registry scopes hold what a fresh sign-in would see, which is what the repair is trying to reconstruct. Ordering is preserved on purpose. The process value stays first in the join, so every directory that resolved before still wins, and the registry values only add what was missing. mergePathValues already drops the duplicates case-insensitively downstream.

Testing

  • npx vitest run --root packages/shared shell.test.ts passes, 30 tests.
  • tsgo --noEmit is clean for packages/shared.
  • The new assertion pins the full ordered statement sequence as text, because the generated command cannot execute on the machines that run this suite. The pin fails if the scoped reads are discarded, reordered, joined with the wrong separator, or left unfiltered.
  • On Windows 11 with process PATH limited to C:\Windows\System32 and Node registered only in the User registry PATH, the repaired environment contains the Node directory, resolveSpawnCommand("npm", ["--version"]) resolves the full npm.CMD path with shell: true, and the command exits 0.

Note

Medium Risk
Touches core Windows spawn/PATH repair used for Node and CLI resolution; behavior change is narrow (PATH capture only) but affects command discovery when the inherited PATH is stale.

Overview
Fixes Windows PATH repair when the app inherits a stale process PATH (e.g. Node added to User/Machine registry after launch). buildWindowsEnvironmentCaptureCommand now, for PATH only, reads the unscoped value plus Machine and User registry scopes, joins non-empty segments with ; (process value first); other captured names still use a single unscoped read. Downstream mergePathValues continues to dedupe.

A new unit test locks the generated PowerShell statement order for PATH and confirms vars like FNM_DIR do not get scoped reads.

Reviewed by Cursor Bugbot for commit 8ff87e5. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix readEnvironmentFromWindowsShell to read Machine and User registry PATH scopes on Windows

Previously, buildWindowsEnvironmentCaptureCommand in shell.ts read PATH using a single unscoped [Environment]::GetEnvironmentVariable call, which only returned the process-level value. Now, when the variable name is PATH, the generated PowerShell reads from the process, Machine, and User registry scopes separately and joins the non-null results with ;. Non-PATH variables continue to use the single unscoped read.

Macroscope summarized 8ff87e5.

The PowerShell probe read PATH with no scope. That returns the PATH the
probe inherited from the app process itself, so a directory the user
registered after the app's parent process started stayed invisible for
the life of the app. With npm invisible, the one-click provider update
spawned bare "npm" with shell disabled, which Node cannot start for a
.cmd shim, and the update died with NotFound.

The capture command now also reads the Machine and User registry scopes
for PATH and joins the non-empty values, process value first, so an
entry that already resolved keeps winning and registry entries only add
what was missing. Other captured names keep the single unscoped read.
The new test pins the exact generated statement sequence, which is the
only guard the suite can provide for a command that never executes on
the machines that run it.
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b09f1d73-a8f3-4304-a80b-60550f853113

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 18, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR changes runtime behavior for Windows PATH resolution by reading additional registry scopes (Machine and User). While well-tested and scoped to PATH only, this alters how environment variables are assembled and warrants human verification of the intended behavior.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

t3dotgg commented Aug 28, 2026

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

We are keeping OPEN #8465 as the review path for refreshing the Windows PATH before provider checks. The registry-scope tests here remain useful reference.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotgg t3dotgg closed this Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: One-click provider update fails with spawn NotFound when the app inherits a stale Windows PATH

2 participants