Skip to content

Windows: every spawned console process flashes a black window (git.exe ~1/sec on v2.0.20) — re-report of #22414, #31629 #52266

Open

Description

@herjarsa

Description

On Windows, every console-subsystem process opencode spawns allocates a visible console window, because the spawn does not pass CREATE_NO_WINDOW. The windows open and close instantly — roughly 1 per second.

git.exe is the most visible case. From ~/.local/share/opencode/log/opencode.log:

message="spawning process" command="C:\Program Files\Git\cmd\git.EXE"
  args="[\"--git-dir\",\"C:\Users\herna\.config\opencode\.git\",\"--work-tree\",...]"

Rate: 417 git.exe spawns in the last 20 000 log lines, 60-68 per minute, in bursts of ~6 within 350 ms. They come from the project repo and from the snapshot repo (~/.local/share/opencode/snapshot/<id>/.git).

Same for any local MCP whose command is a console binary (node.exe, python.exe): one window per MCP start.

Mechanism: a console-subsystem child of a GUI-subsystem parent calls AllocConsole(). Only the spawner can suppress it, via CREATE_NO_WINDOW or DETACHED_PROCESS.

Previously reported and closed administratively rather than fixed: #22414 and #31629 (60-day inactivity), #38715 (auto-closed), #42440 (COMPLETED, but last comment is "I will screen record it later today if you still cant replicate it"). Still reproduces on v2.0.20.

Plugins

@herjarsa/omo-meta-governor@latest
opencode-omniroute-plugin@latest
superpowers@git+https://github.com/obra/superpowers.git

OpenCode version

v2.0.20

Steps to reproduce

1. Windows 11, open the desktop app with a few projects open.
2. Work normally (or open a session in an active project).
3. Watch for black console windows opening and closing ~1 per second.

Confirmed by log count rather than by eye: count spawning process lines mentioning git.EXE in opencode.log.

Screenshot and/or share link

No screenshot: the windows close in under a second, so a capture is not practical. Log excerpt above is the reproducible evidence.

Operating System

Microsoft Windows 11 Pro Insider Preview  build 28120.10.0.28120

Terminal

Windows Terminal 1.24.11911.0  (also affects the desktop app, which spawns without a terminal host)

Notes

Workarounds tried, all of which failed:

  • Delegated console host via HKCU\Console\%%Startup — made it worse, any console app started an endless window loop.
  • Windows Terminal windowingBehavior: "useExisting" — no effect.
  • A GUI-subsystem launcher wrapping each MCP with CreateNoWindow + stdio relay — works with file-redirected stdio, but under opencode live pipes every MCP fails with mcp connect failed ... "Request timed out".
  • Removing cmd.exe/npx shims from MCP definitions — fewer processes, but node.exe is still a console app, so the window remains.

"snapshots": false reduces the churn (it removes the snapshot-repo git calls) but costs file undo/revert, and does not affect project-repo git calls.

Activity

  1. added
    needs:complianceThis means the issue will auto-close after 2 hours.
    and removed
    needs:complianceThis means the issue will auto-close after 2 hours.
    on Sep 30, 2026
  2. github-actions commented on Sep 30, 2026

    @github-actions
    Contributor

    Thanks for updating the issue with the Bug Report template and the reproduction and system details. It now meets our issue guidelines.

  3. lovesans commented on Sep 30, 2026

    @lovesans

    1.18.33 same problem

  4. CN6 commented on Oct 8, 2026

    @CN6

    Environment

    • OpenCode version: Desktop 2.0.24 (@opencode-aidesktop, bundled resources/opencode-cli.exe)
    • OS: Windows 11 Insider build 10.0.28020; default terminal: Windows Terminal
    • Plugins: superpowers@git+https://github.com/obra/superpowers.git, opencode-skills-collection@latest

    Reproduction

    1. Launch the OpenCode desktop app on Windows.
    2. A black console window (git) flashes once, immediately at startup.
    3. Reproduces on every launch observed today.

    Evidence

    The flash coincides with the startup worktree probe in ~/.local/share/opencode/log/opencode.log:

    timestamp=2026-10-08T09:15:55.127Z level=WARN message="worktree discovery failed"
      directory="D:\opencode-data" strategy=git error=Worktree.DirectoryUnavailableError http.span=1184ms
    

    No config switch exists for worktree discovery, so opencode.jsonc cannot work around it.

    Cross-ref: #52281, #53730, #50868 (open) / #31629, #42440, #22414 (closed).

  5. rabbix404 commented on Oct 20, 2026

    @rabbix404

    Same here on v2.0.32 — still reproduces. Every agent turn that runs a tool (local MCP/plugin or shell) flashes 5–10 Terminal windows in milliseconds.

    Verified spawn chain on Windows 11: opencode-cli.exe serve --service → deja.exe mcp (stdio MCP server) with a visible console. Same binary runs silent under other hosts, so it's the spawn flags, not the child process.

    Please re-look at #52594 — the hidden-console fix never merged and this path still fires.

  6. ahmadgamal15-art commented on Oct 23, 2026

    @ahmadgamal15-art

    Measured attribution data (watcher-based) confirming the tool-call correlation

    Independent 45-minute process-creation watch (0.5s poll, CIM Win32_Process, full parent chains logged) on Windows 11 10.0.26200, opencode 2.0.29 (@opencode/cli, opencode.exe serve --service):

    22 powershell.exe spawns in the window, attributed by parent:

    count parent process chain
    5 opencode.exe serve --service opencode → powershell.exe (the agent's own shell tool — every tool command)
    4 bash.exe -c "source /c/Users/ahmad/.claude/..." Claude Code tool chain → powershell.exe
    3 claude.exe (desktop app) → powershell.exe
    9 parent exited before sampling spawn-and-exit pattern, consistent with short-lived tool helpers
    1 explorer.exe manual

    Two effects worth folding into the fix:

    1. The flash is per-tool-call, not per-session. The popup rate tracks agent command volume exactly — a busy agent session produces a visible console on the user's desktop every few seconds. Both the agent's own shell tool AND its spawned helper chains (bash → powershell) are affected, so hiding only the direct shell spawn will not be sufficient; windowsHide (or CREATE_NO_WINDOW) needs to apply to the whole spawned tree.
    2. The silent-degradation trap makes this hard to notice in service mode: when the server runs detached (opencode.exe serve --service), the agent works fine — only the user's desktop suffers, so the bug reads as "some other process" rather than the agent itself. A per-spawn windowsHide on every child_process call in the server process (shell tool, MCP stdio spawns, updater probes) is the complete fix.

    Happy to re-run the watcher against a fix build to verify. Watcher script (70-line PowerShell, no deps): available on request.

  7. fxMT-nx commented on Oct 23, 2026

    @fxMT-nx

    Fresh data confirming this on OpenCode Desktop 2.1.3 (Windows 11 26300) - still reproduces, 100% of launches, with measured per-launch counts. In my case the parent is the Electron app rather than a terminal-launched CLI.


    Summary

    On Windows 11, launching OpenCode Desktop 2.1.3 flashes a burst of visible console windows (17-67 per launch, all within the first ~30 s) before/while the UI paints. The windows are the console-subsystem children that the background service (opencode-cli.exe serve --service) spawns for startup project probing - mostly git.exe, plus rg.exe and powershell.exe. Because the Electron parent has no console attached, each child allocates its own visible console.

    Environment

    • opencode version: 2.1.3 (OpenCode Desktop, @opencodedesktop; bundled opencode-cli.exe 2.1.3-x64, log reports version=2.1.3 channel=latest local=false)
    • OS: Microsoft Windows 11 Pro, 10.0.26300, build 26300 (win32 x64)
    • Terminal: none - OpenCode Desktop (Electron GUI). Default console app is the legacy console host (HKCU\Console\%%Startup unset), so the flashes are plain black conhost windows, not Windows Terminal tabs.
    • Shell: cmd.exe (%ComSpec%); the agent shell tool runs powershell.exe -NoLogo -NoProfile -NonInteractive
    • Install/channel: desktop app at %LOCALAPPDATA%\Programs\@opencodedesktop\OpenCode.exe, cli latest, not local/dev
    • Active plugins: superpowers@git+https://github.com/obra/superpowers.git, local ~/.config/opencode/plugins/context-mode.ts
    • MCP servers: two remote servers (browseros 127.0.0.1:9200, browseros-neo 127.0.0.1:9010) - no stdio MCP servers, so local MCP startup is not involved here

    Reproduction

    1. On Windows 11, start OpenCode Desktop (any launch - not limited to the first launch after boot).
    2. Watch the screen for the first 30 seconds.
    3. Many black console windows open and close in rapid succession.
    4. Confirm in ~/.local/share/opencode/log/opencode.log: each message="cli starting" version=2.1.3 args=["serve","--service"] is followed by a burst of message="spawning process" lines.

    Expected Behavior

    No visible console window should appear. Children of the detached background service should be created hidden (CREATE_NO_WINDOW / DETACHED_PROCESS, or windowsHide: true), the same way the agent shell tool spawns powershell.exe today (that child reports MainWindowHandle=0).

    Actual Behavior

    Every launch produces a burst of visible console windows. Counted from spawning process entries within 30 s of each cli starting ... ["serve","--service"] event in opencode.log:

    launch (UTC) child processes in first 30 s
    2026-10-22 22:17:29 67
    2026-10-22 23:26:08 39
    2026-10-23 09:49:12 19
    2026-10-23 22:08:03 17

    Breakdown for the last launch (18 spawns in 40 s, 7 distinct kinds):

     8  git.EXE --no-optional-locks -c core.autocrlf=false -c core.fsmonitor=false ...
     4  git.EXE rev-parse --git-dir --git-common-dir --show-toplevel
     2  git.EXE remote get-url origin
     1  git.EXE worktree list --porcelain
     1  rg.exe  --no-config --files --glob=!**/.git/** .
     1  powershell.EXE -NoLogo -NoProfile -NonInteractive -Command "Get-Content ..."
    

    Aggregate over the current log (105 589 lines):

    37922  C:\Program Files\Git\cmd\git.EXE
     3738  C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.EXE
      586  ...\ripgrep-15.2.0-x86_64-pc-windows-msvc\rg.exe
    

    Additional Context


    Published on behalf of the reporter from a support session; log excerpts are aggregate counts from my local opencode.log, no session content or secrets included.

  8. thaihoc215 commented on Oct 27, 2026

    @thaihoc215

    Same problem reported at: #59478
    Have tried: opencde --standalone as suggestion and seem that works, no popping up black terminal window and taking focus while working with opencode

  9. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed report and the log counts. I can't reproduce this here: it only happens on Windows, and our automated environment runs on Linux. A maintainer with a Windows machine will need to look at it.

    One thing that may help narrow it down: in v2.0.20 the spawner that runs git and stdio MCP servers already passes windowsHide: true on Windows. That's the Node option that sets CREATE_NO_WINDOW. So the windows may come from a different path. One possibility is that the background service is started detached and has no console of its own, which is what the unmerged #45259 tried to address. Another is a plugin that starts processes itself. If you can, check whether the flashing still happens with your plugins (@herjarsa/omo-meta-governor, opencode-omniroute-plugin, superpowers) temporarily removed, and whether it shows up with the CLI as well as the desktop app.

    Related issues:

  10. asv-netizen commented on Oct 29, 2026

    @asv-netizen

    Confirming this on 2.2.1 with no plugins at all — the plugins-disabled check requested above.

    • Desktop app 2.2.1.0, bundled CLI opencode v2.2.1
    • Windows 11 26H2 (10.0.26300), Windows Terminal 1.24.12741.0 as the default terminal application
    • ~/.config/opencode contains only skills/ and service.json; the project .opencode/ contains only agents/ and commands/. No plugin entries, no local plugins, no MCP servers.
    • The project is not a git repository, yet the service still runs the core worktree probe. From opencode.log:
    timestamp=2026-10-29T09:57:39.022Z level=WARN message="worktree discovery failed" directory="<project>" strategy=git error=Worktree.DirectoryUnavailableError http.span=23 role=server
    

    A local WinEvent hook that hides console windows whose process is a descendant of opencode-cli.exe removes the visible flashing, but the spawn flags are unchanged. Happy to test a build that attaches a hidden console to the service or passes CREATE_NO_WINDOW on this path.

  11. nathwn12 commented on Nov 10, 2026

    @nathwn12

    Attribution found: the cmd.exe /d /s /c "opencode service status" heartbeat came from a plugin, not core.

    The earlier triage note was right that core never issues this, and right that the global plugin directory was the place to look. It was there.

    Environment

    • opencode v2.2.7 now (v2.2.6 when reported), bun global install, Windows 11 Pro 26300
    • background service opencode serve --service running for the whole measurement
    • plugin: oc-phone-link (mine), a directory plugin at ~/.config/opencode/plugins/oc-phone-link, so it appears in neither the plugins array nor the report

    The code that issued it (introduced in f99681f, plugin/oc-phone-link/beacon.mjs):

    const run = (args) => {
      const r = spawnSync("opencode " + args.join(" "), { encoding: "utf8", shell: true, timeout: 20000 });
      return { ok: r.status === 0, out: (r.stdout || "").trim(), err: (r.stderr || "").trim() };
    };
    ...
    const s = run(["service", "status"]);           // upstream port discovery
    const r = run(["service", "get", "password"]);  // pairing credential

    shell: true on a joined command string is exactly what produces:

    cmd.exe /d /s /c "opencode service status"
    

    and the same shape for service get password. Plugins load inside the OpenCode process, so the child's parent is OpenCode itself — in service mode, opencode serve --service. That is why the parent chain in the trace looked like the core daemon: it was the core daemon, running a plugin. No core code needed to shell out for the command to appear.

    Fixed in oc-phone-link 1.5.3 (commit 5ba58a9, 2026-11-10), by removing the shell path entirely:

    const r = spawnSync("opencode", args, { encoding: "utf8", windowsHide: true, timeout: 20000 });
    • argv array, no shell: no cmd.exe in the chain
    • windowsHide: true
    • the upstream port now comes from the server's own listening socket (netstat, also argv + windowsHide) instead of service status
    • the password comes from the environment, with at most one hidden CLI call as a fallback

    Measurement after the fix (v2.2.7, plugin 2.0.6, service running): a 20 s WMI __InstanceCreationEvent watch on Win32_Process where Name='cmd.exe' recorded 16 starts — all agent shell/test commands (npm run test, tsc --noEmit, and similar) — and 0 whose command line contained opencode service.

    So the window in #62988 was gone at the source. The duplicate still stands on the root cause (#52266), not on attribution: a console child of a console-less service gets a fresh, foreground-taking console window.

    On #60471: I can't honestly post the requested trace against a build containing it, because I don't have one — that would mean building opencode from source with the PR applied, and I haven't done that. I won't report a result I didn't measure. What I can say is that this particular spawn no longer exists, and #60471 still covers every other console child that a plugin, MCP server, or core path starts. If someone can point at a build with #60471 in it, I'll run the same watcher against it and post the numbers.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions