Windows: child processes spawn visible conhost.exe windows

Resolved 💬 3 comments Opened Apr 5, 2026 by rahim0kapadia Closed Apr 9, 2026

Summary

On Windows, claude.exe is a console subsystem binary. When it spawns child processes (Bash tool calls, MCP servers), those children inherit the console subsystem type but have no console to attach to — particularly in headless (-p) mode or when the parent is spawned with windowsHide: true. Windows responds by creating a new conhost.exe instance (a visible command prompt window) for each child process.

Steps to reproduce

  1. On Windows 11, run claude -p from a Node.js script:

``js
const { spawn } = require('child_process');
const child = spawn('claude', ['-p', 'list files in the current directory'], {
windowsHide: true
});
``

  1. Observe a conhost.exe window appearing when the Bash tool call executes.
  2. Run a prompt that starts MCP servers — each server spawns 1–2 persistent visible windows.

Expected behavior

Child processes spawned by claude.exe should not create visible console windows. The fix is to pass CREATE_NO_WINDOW (0x08000000) via dwCreationFlags — or equivalently, set windowsHide: true in Node.js child_process.spawn() options — when spawning:

  1. Bash tool shell processes (bash.exe, cmd.exe)
  2. MCP server processes (cmd.exe, node.exe, npx, uvx)

Actual behavior

Every child process creates its own conhost.exe, resulting in visible command prompt windows on the desktop.

Impact

| Scenario | Visible windows created |
|---|---|
| Single Bash tool call | 1 window flash per call |
| run_in_background: true Bash call | 1 persistent window that never closes |
| 1 MCP server | 1–2 persistent windows per session |
| 5 MCP servers across 3 sessions | 30+ command windows on the desktop |

This makes claude -p (programmatic mode) unusable for background automation on Windows. Users running Claude Code from scripts, schedulers, or GUI wrappers see a flood of command prompt windows.

Why this happens

  • claude.exe is compiled as a console subsystem binary (PE header subsystem = IMAGE_SUBSYSTEM_WINDOWS_CONSOLE).
  • When a console app spawns a child process without explicit creation flags, Windows gives the child a console. If the parent's console is hidden or absent, Windows creates a new conhost.exe for the child.
  • Setting windowsHide: true on the outer claude.exe spawn only hides claude.exe's own console allocation — it does not propagate to internally spawned children.

Suggested fix

In the Node.js code that spawns child processes (Bash tool execution and MCP server startup), add windowsHide: true to the spawn/execFile options:

spawn(command, args, {
  // existing options...
  windowsHide: true  // sets CREATE_NO_WINDOW on Windows, no-op on other platforms
});

This is a one-line change per spawn site and has no effect on macOS/Linux.

Workaround

Users can wrap the initial claude.exe invocation with a GUI-subsystem launcher (e.g., a .NET exe compiled with /target:winexe, or a VBScript with WScript.CreateObject("WScript.Shell").Run). This prevents claude.exe's own console but does not fix the internal child process windows.

Environment

  • OS: Windows 11 (10.0.26200)
  • Claude Code: CLI (claude.exe)
  • Shell: Git Bash / PowerShell

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗