Skip to content

Windows: ENOENT on all tool calls + prompt argument splitting breakage #34

@AnshulJ999

Description

@AnshulJ999

Platform

  • OS: Windows 11
  • Node.js: v22+ (any version)
  • gemini-mcp-server: v1.1.1 (latest)
  • Gemini CLI: 0.29.7

Description

The MCP server has two bugs that together make it completely non-functional on Windows.
They manifest in sequence — fix the first and the second appears.


Bug 1: spawn gemini ENOENT — all tool calls fail immediately

Error:

Failed to spawn command: spawn gemini ENOENT

Root cause: commandExecutor.ts calls spawn(command, args, { shell: false }).
On Windows, shell: false bypasses cmd.exe entirely and uses the raw Win32
CreateProcess API, which cannot resolve bare command names from PATH. It requires
a full absolute path to the executable. Since gemini is an npm global binary (a .cmd
wrapper script), Windows cannot find it without going through the shell.

Fix in src/utils/commandExecutor.ts:

const childProcess = spawn(command, args, {
    env: process.env,
    shell: process.platform === 'win32',  // was: shell: false
    stdio: ['ignore', 'pipe', 'pipe'],
});

Bug 2: Prompt split into multiple args — conflict error

Error:

Cannot use both a positional prompt and the --prompt (-p) flag together

Root cause: After fixing Bug 1, shell: true is active on Windows. Node.js passes
arguments to cmd.exe by joining the entire args array into a single space-delimited
string. The current quoting logic in geminiExecutor.ts only wraps the prompt in quotes
when it contains an @ symbol:

const finalPrompt = prompt_processed.includes('@') && !prompt_processed.startsWith('"')
    ? `"${prompt_processed}"`
    : prompt_processed;  // ← no quotes for normal prompts!

When cmd.exe receives e.g. gemini -m gemini-3-pro-preview -p What is 2+2?, it splits
on spaces, so -p only receives What as its value, and is, 2+2? etc. become
positional query arguments — which conflicts with -p.

Fix in src/utils/geminiExecutor.ts — apply at BOTH the main prompt and fallback prompt locations:

const isWindows = process.platform === 'win32';
const finalPrompt = isWindows
    ? `"${prompt_processed.replace(/"/g, '""')}"`
    : (prompt_processed.includes('@') && !prompt_processed.startsWith('"')
        ? `"${prompt_processed}"`
        : prompt_processed);

This always double-quotes the prompt string on Windows, with internal " characters
escaped as "" per cmd.exe conventions.


Summary

Both issues stem from the same underlying assumption: the code was written for Unix-like
environments where bare command names resolve via PATH without a shell, and argument
tokenization is not a concern. On Windows, shell: true is needed for PATH resolution,
and any multi-word argument must be explicitly quoted to avoid being split by cmd.exe.

Happy to submit a PR with these two fixes if that would be helpful.

I did use AI to draft the above issue, and was able to fix it on my local machine by editing the files directly. However they'll get overwritten when this project gets updated, so please fix this when possible. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions