gemini-cli - ✅(Solved) Fix Windows: Regression - run_shell_command strips double quotes [1 pull requests, 3 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
google-gemini/gemini-cli#25859Fetched 2026-04-24 06:13:56
View on GitHub
Comments
3
Participants
2
Timeline
16
Reactions
0
Author
Participants
Timeline (top)
mentioned ×4subscribed ×4commented ×3labeled ×3

On Windows, run_shell_command incorrectly strips double quotes from commands, even when they are properly enclosed in single quotes or escaped. This breaks any tool that requires quoted arguments (Node.js, JDT, JSON parsers).

Error Message

ReferenceError: test is not defined at [eval]:1:13

Root Cause

Technical Root Cause

The issue is caused by wrapping commands in powershell.exe -NoProfile -Command "...". When the outer wrapper is a double-quoted string, internal double quotes are lost or mangled during the process spawn on Windows.

Fix Action

Fixed

PR fix notes

PR #25900: fix(core): prefer pwsh.exe over Windows PowerShell 5.1 (#25859)

Description (problem / solution / changelog)

Summary

Fixes #25859. Related: closes-as-effectively-same #18374; addresses the feature-request spirit of #15493, #2353, #6413.

On Windows, run_shell_command with embedded double quotes (e.g. node -e 'console.log(\"test\")') fails because Windows PowerShell 5.1 silently strips \" during native-command argument passing. PowerShell 7 (pwsh.exe) uses standards-compliant argument passing (\$PSNativeCommandArgumentPassing = 'Windows' by default since 7.3) and does not exhibit this behavior.

This PR makes getShellConfiguration prefer pwsh.exe from PATH over powershell.exe on Windows. Users with PowerShell 7 installed get the fix; users without keep the existing behavior — no regression either way.

Context

Windows PowerShell 5.1 is in legacy maintenance mode. Microsoft itself displays this banner when 5.1 starts:

``` Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows ```

PS 5.1 is .NET Framework-bound, Windows-only, and lags PS 7 on shell behavior. `$PSNativeCommandArgumentPassing` (fixes native-cmd arg passing) and bash-style `&&`/`||` chain operators were added in PS 7 and cannot be backported to 5.1.

Respecting the user's environment. gemini-cli is a developer tool, and developers who work on Windows overwhelmingly install PowerShell 7 — it's the modern, cross-platform, actively-maintained runtime Microsoft recommends. Currently gemini-cli ignores the user's choice and pins Windows invocations to `powershell.exe` (5.1 on any modern Windows) regardless of whether pwsh 7 is installed. This PR follows both Microsoft's own guidance and the user's clear intent: prefer PS 7 when it's on their system, fall back to 5.1 only when it isn't.

Side benefits

PowerShell 7 also addresses other Windows-specific pain reported against gemini-cli:

  • `&&` / `||` operators (added in PS 7.0): unblocks #20773, #18022, #21997. LLM-generated commands with bash-style `&&` will parse correctly on pwsh 7.
  • UTF-8 by default (PS 7): improves the encoding issues reported in #20968, #12468, #20186 (avoids 5.1's legacy codepage mangling).

These aren't explicitly targeted by the fix but improve as a natural consequence for users who have pwsh 7 installed.

Verification

Reproduce directly in each shell — same commands, different results.

Issue 1: embedded double quotes stripped (#25859)

Windows PowerShell 5.1: ``` PS C:\Users\EugenPC> node -e 'console.log("test")' [eval]:1 console.log(test) ^ ReferenceError: test is not defined at [eval]:1:13 ... Node.js v22.18.0 ```

PowerShell 7.6.1: ``` PS C:\Users\EugenPC> node -e 'console.log("test")' test ```

Issue 2: `&&` / `||` operators rejected (#20773, #21997, #18022)

Windows PowerShell 5.1: ``` PS C:\Users\EugenPC> echo a && echo b At line:1 char:8

  • echo a && echo b
  •    ~~

The token '&&' is not a valid statement separator in this version. ```

PowerShell 7.6.1: ``` PS C:\Users\EugenPC> echo a && echo b a b ```

With this PR, gemini-cli routes through `pwsh.exe` on Windows when it's installed, inheriting the correct behavior for both issues.

Behavior matrix

EnvironmentBeforeAfter
Windows + `pwsh.exe` in PATHpowershellpwsh (fix)
Windows, no `pwsh.exe`powershellpowershell
Windows, explicit `ComSpec`honoredhonored
Windows sandbox (`windows-native`)cmd.exe /ccmd.exe /c
macOS / Linuxbashbash

Only the first row changes behavior.

Tests

  • Unit tests in `shell-utils.test.ts` covering new pwsh preference, path-extension handling, unset `PATH`.
  • New Windows-only integration file (`shellExecutionService.windows.integration.test.ts`, skipped on non-Windows): 5 cases driving real spawns through `ShellExecutionService`, asserting byte-exact preservation of embedded `"`.
  • Full core suite: 0 regressions vs. `main`.

Root cause

PR #11157 (2025-10-16) changed the default Windows shell from `cmd.exe /d /s /c` to `powershell.exe -NoProfile -Command`. Windows PowerShell 5.1 lacks `$PSNativeCommandArgumentPassing` (introduced in PS 7.2 as experimental, default since 7.3) and has a long-standing runtime limitation: `"` inside arguments is dropped when invoking native executables. Fixable only by running through PS 7 — which is what this PR does.

Changed files

  • packages/core/src/hooks/hookRunner.test.ts (modified, +3/-3)
  • packages/core/src/services/shellExecutionService.test.ts (modified, +2/-2)
  • packages/core/src/services/shellExecutionService.ts (modified, +1/-2)
  • packages/core/src/services/shellExecutionService.windows.integration.test.ts (added, +89/-0)
  • packages/core/src/utils/shell-utils.test.ts (modified, +58/-41)
  • packages/core/src/utils/shell-utils.ts (modified, +36/-18)

Code Example

ReferenceError: test is not defined
    at [eval]:1:13
RAW_BUFFERClick to expand / collapse

Description

On Windows, run_shell_command incorrectly strips double quotes from commands, even when they are properly enclosed in single quotes or escaped. This breaks any tool that requires quoted arguments (Node.js, JDT, JSON parsers).

Steps to Reproduce

Run the following command via Gemini CLI on Windows: !node -e 'console.log("test")'

Expected behavior: Output: test

Actual behavior:

ReferenceError: test is not defined
    at [eval]:1:13

The CLI strips the double quotes around test, so Node receives console.log(test) instead of console.log("test").

Technical Root Cause

The issue is caused by wrapping commands in powershell.exe -NoProfile -Command "...". When the outer wrapper is a double-quoted string, internal double quotes are lost or mangled during the process spawn on Windows.

Suggested Fix

Use -EncodedCommand for Windows shell execution. Encoding the command string as Base64 (UTF-16LE) is the only reliable way to ensure that complex strings and quotes are preserved exactly as intended by the model.

Environment

  • OS: Windows 10/11
  • Gemini CLI Version: 0.39.0 (Latest Stable)

extent analysis

TL;DR

Switch to using the -EncodedCommand option with Base64 encoding for Windows shell execution to preserve double quotes in commands.

Guidance

  • Verify that the issue is indeed caused by the command wrapping in powershell.exe -NoProfile -Command "..." by checking the command execution logs or debugging the command spawn process.
  • Test the suggested fix by modifying the run_shell_command function to use the -EncodedCommand option with Base64 encoding, ensuring that complex strings and quotes are preserved.
  • Consider updating the Gemini CLI documentation to reflect the recommended approach for handling quoted arguments on Windows.
  • Validate that the fix works for various tools that require quoted arguments, such as Node.js, JDT, and JSON parsers.

Example

# Example of using -EncodedCommand with Base64 encoding
$command = "console.log(\"test\")"
$encodedCommand = [System.Text.Encoding]::UTF8.GetBytes($command)
$base64Command = [Convert]::ToBase64String($encodedCommand)
powershell.exe -NoProfile -EncodedCommand $base64Command

Notes

The provided fix relies on the -EncodedCommand option, which may have specific requirements or limitations on Windows. Ensure that the Base64 encoding is correctly implemented to avoid any issues.

Recommendation

Apply the workaround by using the -EncodedCommand option with Base64 encoding, as it is the only reliable way to preserve complex strings and quotes on Windows.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING