Repository: google-gemini/gemini-cli (TypeScript)

Issue:
Gemini CLI: Unable to handle spaces in file paths/names on Windows
### What happened?

I attempted to perform file operations (rename and delete) on a file with a Cyrillic name ("Важность.md") located in a directory with a Cyrillic name ("База данных") using `run_shell_command` on a Windows system.
- Reading the file content using `read_file` was successful.
- Modifying the file content using `replace` was successful.
- Renaming the file using `mv`, `ren`, and `move` commands failed with the error "The filename, directory name, or volume label syntax is incorrect."
- Deleting the file using the `del` command also failed with the error "The filename, directory name, or volume label syntax is incorrect."

### What did you expect to happen?

I expected to be able to rename and delete files with Cyrillic characters in their names or paths using `run_shell_command` on Windows, similar to how `read_file` and `replace` successfully handled the file. The shell commands should correctly interpret and execute operations on files with non-ASCII characters.

### Client information


* **CLI Version:** 0.1.15
* **Git Commit:** c45c14ee (local modifications)
* **Operating System:** win32 v22.17.1
* **Sandbox Environment:** no sandbox
* **Model Version:** gemini-2.5-flash
* **Memory Usage:** 150.9 MB


### Login information

Google Account

### Anything else we need to know?

_No response_


Discussion:
I can reproduce this.

> ✦ I will rename the directory "База данных" to "foo".
>   │ ✔  Shell ren "База данных" "foo" (Renames the directory 'База данных' to 'foo' in the current directory.)                                                       │✦ The command failed. It seems I cannot rename a directory with ren like that. I will try with the move command instead. I will move "База данных" to "foo", which on
>   Windows has the effect of renaming it.
> │ ✔  Shell move "База данных" "foo" (Renames the directory 'База данных' to 'foo' using the 'move' command.)                                                      ✦ It seems like the previous command failed because the directory "База данных" does not exist. I will list the contents of the current directory to verify.
> ✦ I see the directory "База данных" exists. I am not sure why the move command failed. I will try again, but this time I will use the full paths.
Note that this does not reproduce on macOS
Further investigation revealed that the issue is not limited to Cyrillic characters. The same errors ("The filename, directory name, or volume label syntax is incorrect." or "The system cannot find the file specified.") consistently occur when attempting to rename or delete files with `ren`, `move`, or `del` commands, even when filenames and paths contain only ASCII characters and are correctly quoted. This suggests a more fundamental problem with how `run_shell_command` interacts with the Windows command shell and interprets file paths, rather than solely an encoding issue.
Hmm. I'm not able to reproduce this with regular ascii characters 

```
╭───────────────────────────────────╮
│  > create a directory called foo  │
╰───────────────────────────────────╯

✦ I will run mkdir foo to create the directory.
 ╭───────────────────────────────────────────────────────╮
 │ ✔  Shell mkdir foo (Create a directory named 'foo'.)  │
 ╰───────────────────────────────────────────────────────╯
✦ Okay, the directory foo has been created.

╭───────────────────────────────────╮
│  > rename the directory to "bar"  │
╰───────────────────────────────────╯

✦ I will run rename foo bar to rename the directory.
 ╭─────────────────────────────────────────────────────────────────╮
 │ ✔  Shell rename foo bar (Rename the directory 'foo' to 'bar'.)  │
 ╰─────────────────────────────────────────────────────────────────╯
✦ The directory has been renamed to bar.
```
Spaces trigger the bug as I can reproduce it by using a Space character with the prompt `create a directory called "foo bar"`.

Cyrillic letters without spaces DO NOT seem to trigger it. I used the prompt `create a directory called Важность` and then `rename it to bar` and it worked fine.
Same for me on a Mac using files with spaces in their filename. Experienced problems reading both .png and .pdf, and then changed the filenames to be without spaces. After that, Gemini was able to read them. 

Filenames:
Screenshot 2025-07-30 at 19.58.45.png
Asset Protection Agent - Macro Risk, v2.pdf



Patch:
diff --git a/packages/core/src/services/shellExecutionService.ts b/packages/core/src/services/shellExecutionService.ts
index 0f0002cdee5..d1126a7d4e0 100644
--- a/packages/core/src/services/shellExecutionService.ts
+++ b/packages/core/src/services/shellExecutionService.ts
@@ -89,13 +89,16 @@ export class ShellExecutionService {
     abortSignal: AbortSignal,
   ): ShellExecutionHandle {
     const isWindows = os.platform() === 'win32';
-    const shell = isWindows ? 'cmd.exe' : 'bash';
-    const shellArgs = [isWindows ? '/c' : '-c', commandToExecute];
 
-    const child = spawn(shell, shellArgs, {
+    const child = spawn(commandToExecute, [], {
       cwd,
       stdio: ['ignore', 'pipe', 'pipe'],
-      detached: !isWindows, // Use process groups on non-Windows for robust killing
+      // Use bash unless in Windows (since it doesn't support bash).
+      // For windows, just use the default.
+      shell: isWindows ? true : 'bash',
+      // Use process groups on non-Windows for robust killing.
+      // Windows process termination is handled by `taskkill /t`.
+      detached: !isWindows,
       env: {
         ...process.env,
         GEMINI_CLI: '1',


Test patch:
diff --git a/packages/core/src/services/shellExecutionService.test.ts b/packages/core/src/services/shellExecutionService.test.ts
index 4d1655a2774..cfce08d2d46 100644
--- a/packages/core/src/services/shellExecutionService.test.ts
+++ b/packages/core/src/services/shellExecutionService.test.ts
@@ -91,9 +91,9 @@ describe('ShellExecutionService', () => {
       });
 
       expect(mockSpawn).toHaveBeenCalledWith(
-        'bash',
-        ['-c', 'ls -l'],
-        expect.any(Object),
+        'ls -l',
+        [],
+        expect.objectContaining({ shell: 'bash' }),
       );
       expect(result.exitCode).toBe(0);
       expect(result.signal).toBeNull();
@@ -334,23 +334,31 @@ describe('ShellExecutionService', () => {
   describe('Platform-Specific Behavior', () => {
     it('should use cmd.exe on Windows', async () => {
       mockPlatform.mockReturnValue('win32');
-      await simulateExecution('dir', (cp) => cp.emit('exit', 0, null));
+      await simulateExecution('dir "foo bar"', (cp) =>
+        cp.emit('exit', 0, null),
+      );
 
       expect(mockSpawn).toHaveBeenCalledWith(
-        'cmd.exe',
-        ['/c', 'dir'],
-        expect.objectContaining({ detached: false }),
+        'dir "foo bar"',
+        [],
+        expect.objectContaining({
+          shell: true,
+          detached: false,
+        }),
       );
     });
 
     it('should use bash and detached process group on Linux', async () => {
       mockPlatform.mockReturnValue('linux');
-      await simulateExecution('ls', (cp) => cp.emit('exit', 0, null));
+      await simulateExecution('ls "foo bar"', (cp) => cp.emit('exit', 0, null));
 
       expect(mockSpawn).toHaveBeenCalledWith(
-        'bash',
-        ['-c', 'ls'],
-        expect.objectContaining({ detached: true }),
+        'ls "foo bar"',
+        [],
+        expect.objectContaining({
+          shell: 'bash',
+          detached: true,
+        }),
       );
     });
   });