Skip to content

win32: console window appears for every child process spawned by background service #57907

Closed as duplicate

Description

@Chaitanysai

Summary

On Windows, the background service spawns every child process (git, powershell, rg) with a new visible console window. Because the service runs console-less, Windows allocates a fresh console per spawn, so windows appear continuously during normal work.

Environment

  • opencode version: 2.1.2 (latest channel, npm global install)
  • OS: Windows 11 Home Single Language, build 26300 (win32 x64)
  • Terminal: Windows Terminal (WT_SESSION set), TERM=xterm-256color
  • Shell: C:\WINDOWS\system32\cmd.exe (ComSpec)
  • Install/channel: npm global (%APPDATA%\npm\opencode.cmd), not dev/beta
  • Active plugins: opencode-supervisor, opencode-auto-model, opencode-idle-compaction, github:steverova/kiro-provider, @xberg-io/opencode-liter-llm, @xberg-io/opencode-xberg, kibi-opencode

Reproduction

  1. On Windows 11, install and run opencode so the shared background service is active (opencode service status returns a URL).
  2. Open a workspace that is a git repository and start a session.
  3. Observe the desktop while the session runs, without invoking any tool manually.

Expected Behavior

Child processes spawned by the service run hidden. On Windows this means passing windowsHide: true (or CREATE_NO_WINDOW) to the spawn call, so no console window is allocated.

Actual Behavior

Each spawned process allocates its own console window, which appears on the desktop and steals focus. Windows are visible for git, powershell, and rg invocations. With continuous snapshot/diff activity this produces a near-constant stream of windows.

Evidence from %USERPROFILE%\.local\share\opencode\log\opencode.log — total spawning process records and breakdown by executable:

6887 total spawns
5190  git.EXE
1300  powershell.EXE
 222  rg.exe
 125  opencode.exe

Sample log line:

level=INFO msg="spawning process" command="C:\\Program Files\\Git\\cmd\\git.EXE" \
  args="[\"--git-dir\",\"...snapshot...\",\"--work-tree\",\"E:\\...\",\"ls-files\",...]" role=server

Additional Context

Why this happens: the service is started detached and owns no console. Per Windows process creation semantics, a child created without CREATE_NO_WINDOW/DETACHED_PROCESS from a console-less parent gets a new console allocated, which is shown to the user.

Workaround applied: no user-side config disables the spawns. Setting Windows Terminal as the default terminal application (HKCU:\Console\%%Startup → DelegationConsole/DelegationTerminal = {E12CFF52-A866-4C77-9A90-F570A7AA2C6B}) consolidates the windows into tabs of one window, which reduces visual noise but does not stop the consoles from being created.

Suggested fix: set windowsHide: true on the spawn/execFile calls used by the service for git snapshotting, the shell tool, and rg. Node's child_process defaults this to false, which is what produces the visible window here.

Frequency: consistent, every session; scales with git snapshot activity.

Activity

  1. opencode-agent commented on Oct 21, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report and the spawn counts from the log!

    I think this is a duplicate of #52266, which tracks the same problem: on Windows, console processes started by the background service (snapshot git, shell, MCP servers) each open a visible window.

    Possible duplicates and closely related issues, ordered from most to least likely:

    One note on the suggested fix: core's spawner already passes windowsHide on Windows (packages/util/src/cross-spawn-spawner.ts), so it is not just a missing flag. Earlier threads also found that some of the windows came from third-party plugins. If you can, please check whether the windows still appear with your plugins disabled, or when running with --standalone, and add the result to #52266.

    The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.

  2. Chaitanysai commented on Oct 21, 2026

    @Chaitanysai
    Author

    Thanks — you're right, and I need to correct my own report.

    My suggested fix was wrong. I checked packages/util/src/cross-spawn-spawner.ts on dev: the spawn already passes windowsHide: process.platform === "win32". So "add windowsHide" is not an accurate description of the defect here, and I shouldn't have presented it as the missing one-liner.

    Where my evidence is actually different: the windows I see are cmd.exe and node.exe, not git.exe. In 6,887 spawning process records from my log, the breakdown by executable is:

    git.EXE        5190
    powershell.EXE 1300
    rg.exe          222
    opencode.exe    125
    

    There is no cmd.exe or node.exe entry anywhere in that set. So the windows that prompted the report never pass through the instrumented core spawner at all — they come from plugin-side spawns. In my config that is consistent with plugins invoking npm global .cmd shims (xberg.cmd, liter-llm.cmd) through shell: true, which yields a cmd.exe console and then a node.exe console per invocation. Core's windowsHide structurally cannot cover that path, because the spawn never goes through core.

    To be clear, I'm not claiming this is distinct from #52266 for the service layer — it is the same symptom, and the counts above support that. The only thing I'd ask to be captured in #52266 is the second spawn path, since it has a different owner and a different fix.

    I have not tested --standalone or a plugin-disabled profile with window observation, so I can't confirm or deny the outcome; I won't guess at it. Happy for this to be closed as a duplicate.

  3. opencode-agent commented on Oct 22, 2026

    @opencode-agent
    Contributor

    We haven't heard back, so I'm closing this as a duplicate of #52266. That issue tracks the same problem: on Windows, git, PowerShell and rg processes started by the background service each open a visible console window. Please follow #52266 for updates. If you can, add whether the windows still appear with your plugins disabled or with --standalone, since that helps narrow down where they come from. If your problem turns out to be different, reply here and explain how, and we can reopen this. Thanks for the detailed report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions