fix(exec): resolve PowerShell 7 via where.exe on Windows#96164
fix(exec): resolve PowerShell 7 via where.exe on Windows#96164samson1357924 wants to merge 2 commits into
Conversation
Add where.exe fallback to resolveShellFromPath for Windows App Execution Aliases (reparse points) that fs.accessSync(X_OK) cannot resolve. Uses accessSync(F_OK) instead of existsSync since existsSync returns false for reparse points (Node.js 24.14.0, Windows 26200). Fixes: openclaw#49931 (partial — the core PATH resolution issue)
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Codex review: needs changes before merge. Reviewed June 30, 2026, 11:06 PM ET / 03:06 UTC. Summary PR surface: Source +31, Tests +23. Total +54 across 2 files. Reproducibility: no. independent Windows repro was run in this read-only review. Source inspection confirms current main only probes Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Land the WindowsApps fallback only after it invokes a trusted Do we have a high-confidence way to reproduce the issue? No independent Windows repro was run in this read-only review. Source inspection confirms current main only probes Is this the best way to solve the issue? No as submitted. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fa3c9de45965. Label changesLabel justifications:
Evidence reviewedPR surface: Source +31, Tests +23. Total +54 across 2 files. View PR surface stats
Security concerns:
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing due to inactivity. |
Summary
Add a
where.exefallback toresolveShellFromPath()on Windows to resolve App Execution Aliases (reparse points) thatfs.accessSync(X_OK)cannot detect. This fixes theexectool defaulting to Windows PowerShell 5.1 when PowerShell 7 is installed via Windows Store / WindowsApps.Problem
On Windows,
resolveShellFromPath()usesfs.accessSync(candidate, fs.constants.X_OK)to find executables on PATH. This fails on Windows App Execution Aliases (0-byte reparse points) placed in%LOCALAPPDATA%\Microsoft\WindowsApps\. When PowerShell 7 is installed via the Microsoft Store (not MSI),pwsh.exeonly exists as a reparse point, and the function falls through topowershell.exe(PS 5.1).Root Cause
fs.existsSync()returnsfalsefor reparse points (EACCES), and whilefs.accessSync(X_OK)actually passes, the function tests it on each PATH entry's fully resolved path — but the WindowsApps symlink redirects to an AppX container path thataccessSynccannot follow correctly in all Node.js versions.Fix
Added a Windows-specific
where.exefallback after the existingaccessSyncloop inresolveShellFromPath(). Thewhere.exeutility correctly resolves App Execution Aliases to their real paths. We validate each result withfs.accessSync(path, fs.constants.F_OK)instead offs.existsSync()since the latter returns false for reparse points.This follows the same insight as agent-core's
findBashOnPath()inpackages/agent-core/src/harness/env/nodejs.ts:180, which already useswheresuccessfully.Key Design Decisions
accessSync(F_OK)overexistsSync— Live testing confirmedexistsSyncreturnsfalsefor WindowsApps reparse points (EACCES), whileaccessSync(F_OK)succeeds.spawnSync(already imported by the module) to match the existing sync pattern ofresolveShellFromPath.where.exepath only triggers when the mainaccessSyncloop fails, so there's zero overhead for successful lookups.resolveShellFromPath(); all 8 internal callers (includingresolvePowerShellPath,getShellConfig,getBashShellConfig,resolveWindowsBashPath) benefit automatically.Changes
src/agents/shell-utils.tsresolveShellFromPath()src/agents/shell-utils.test.tsRelated Issues
fa525bf21— PS7 priority inresolvePowerShellPath()Checklist
process.platform === "win32"Real behavior proof
Behavior or issue addressed: On Windows, the
exectool cannot resolve PowerShell 7 installed via Microsoft Store / WindowsApps becausefs.accessSync(X_OK)fails on App Execution Alias reparse points. This causesresolveShellFromPath("pwsh")to returnundefined, falling through topowershell.exe(PS 5.1).Real environment tested:
Exact steps or command run after this patch:
Evidence after fix: Terminal transcript captured after applying the patch:
Observed result after fix:
resolveShellFromPath()correctly resolves executables that exist only as Windows App Execution Aliases (reparse points). On this system,pwsh.exein WindowsApps is resolved and returned as the first match. The existingaccessSync(X_OK)loop continues to work normally for Unix platforms and for regular Windows executables. All 4 resolveShellFromPath tests pass, including the 3 new Windows-specific tests.What was not tested:
cmd.exeviabuildNodeShellCommand, not affected by this change)process.platform === "win32"guard excludes Unix)