fix(shell): use PowerShell CLI args for custom pwsh/powershell shell paths on Windows#104053
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 10, 2026, 10:01 PM ET / July 11, 2026, 02:01 UTC. Summary PR surface: Source +15, Tests +30. Total +45 across 2 files. Reproducibility: no. Direct PowerShell execution succeeds with current main's 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:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Reproduce the exact custom-shell failure on Windows, then make the narrowest shared argument change that fixes the observed behavior while preserving intentional custom-shell profile and interaction semantics. Do we have a high-confidence way to reproduce the issue? No. Direct PowerShell execution succeeds with current main's Is this the best way to solve the issue? No. The patch special-cases executable names and changes profile and interaction behavior to solve a switch rejection that PowerShell's contract and live execution disprove; the actual failing condition must be identified first. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against f50293c9e73b. Label changesLabel justifications:
Evidence reviewedPR surface: Source +15, Tests +30. Total +45 across 2 files. View PR surface stats
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
|
|
I tested the premise on a real Windows setup (PowerShell 7.6.3 and 5.1): So PowerShell does accept The real Windows pwsh gap (which this PR does not address) is in shell discovery, not custom-shell args. If the goal is robust Windows pwsh resolution, the minimal correct fix is in function resolveShellFromPath(name, env = process.env) {
const envPath = env.PATH ?? "";
if (!envPath) return;
const exts = process.platform === "win32" ? ["", ".exe", ".cmd", ".bat"] : [""];
for (const entry of envPath.split(path.delimiter).filter(Boolean)) {
for (const ext of exts) {
const candidate = path.join(entry, name + ext);
try { fs.accessSync(candidate, fs.constants.X_OK); return candidate; } catch {}
}
}
}That makes |
|
Following up with the actual Windows pwsh fix, split into its own PR: #104086. The
#104086 fixes exactly that: Happy to coordinate if maintainers would rather fold the discovery fix into this PR instead of a separate one. |
|
This pull request has been automatically marked as stale due to inactivity. |
Summary
On Windows, when a user sets a custom shell path (
shellPath/settings.shellPath) that points to a PowerShell binary (e.g.pwsh.exefrom the Microsoft Store App Execution Alias, or a custompwshinstall), OpenClaw invoked it with POSIX-style arguments (-c) instead of PowerShell CLI arguments.PowerShell does not accept
-c(it uses-Command), so the exec command was either rejected or silently ignored — making theshellPathsetting effectively broken for PowerShell on Windows.Root cause
In
src/agents/shell-utils.ts,getShellConfig(customShellPath)andgetBashShellConfig(customShellPath)both delegate togetPosixShellArgs(), whosedefaultbranch returns["-c"]. A custompwsh.exe/powershell.exepath fell into that default, producingpwsh.exe -c "...", which is invalid.Note that the non-custom Windows path already uses the correct args (
-NoProfile -NonInteractive -Command) viaresolvePowerShellPath(). The bug only affected the explicitcustomShellPathcase.Fix
isPowerShellShell(shellPath)helper that detectspwsh,pwsh.exe,powershell,powershell.exe.WINDOWS_POWERSHELL_ARGS = ["-NoProfile", "-NonInteractive", "-Command"]instead of the POSIX-cargs.getShellConfigandgetBashShellConfigfor consistency.Test plan
shell-utils.test.tsasserting custompwsh.exe,powershell.exe, andpwsh(no extension) paths yield["-NoProfile", "-NonInteractive", "-Command"].