You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Windows: secondary Codex session spawns visible console windows for child executable calls #44856
On Windows, a primary Codex terminal/session behaves normally, but a second Codex tab/session appears to launch child executable calls in separate visible console windows.
This is reproducible specifically in the secondary session. The primary session does not exhibit the behavior.
Environment
Windows 11
Codex running in terminal tabs
Multiple Codex sessions open concurrently
Windows Terminal used as the terminal host
Reproduction
Start a Codex session in one terminal tab.
Run normal work involving shell/tool calls (pwsh, git, gh, etc.).
Open a second terminal tab and start a second Codex session.
In the second session, run work that triggers shell/tool calls.
Observe that many child executable calls spawn their own visible console/terminal windows.
Actual behavior
In the first/main Codex session, child commands execute without spawning visible external console windows.
In the second Codex session, many executable calls open a separate visible terminal/console window.
The windows typically show a successful exit, e.g.:
[process exited with code 0 (0x00000000)]
You can now close this terminal with Ctrl+D, or press Enter to restart.
Changing Windows Terminal's setting to close automatically on clean exit reduces the symptom from accumulated windows to a brief visible flicker, but the secondary-session child consoles are still being created and remain disruptive.
Expected behavior
Child executable calls in additional Codex sessions should behave like those in the primary session: remain attached to/contained within the existing terminal/PTY (or otherwise run hidden) rather than creating visible transient console windows.
Important differentiator
This does not happen in the main/first Codex tab. It appears tied specifically to running a second concurrent Codex session/tab.
That suggests this may involve secondary-session console/PTY inheritance or Windows process creation flags rather than a generic Windows shell configuration issue.
Impact
The behavior is especially disruptive for autonomous/agent-style workflows that execute many short-lived commands, since each subprocess can cause a visible window flash.
A screenshot is available showing multiple short-lived terminal windows created by the secondary session.
Additional reproduction detail: one child process spawned by the secondary Codex session was not ephemeral. A separate visible window remained open while running:
This makes the issue look less like generic short-lived shell flashing and more like the secondary session is causing Codex child/host processes themselves to be launched into separate visible console windows. The behavior is still specific to the second concurrent Codex tab/session; the primary session does not do this.
Your differentiator is the whole clue, and it points at the shared app-server daemon. It explains both halves of the symptom, including the non-ephemeral codex-code-mode-host.exe window.
The two sessions are not running the same server:
A session that starts before any background server exists runs an embedded app-server inside the TUI process (AppServerClient::InProcess), i.e. inside the Windows Terminal tab that already owns a console.
Once a managed daemon exists, later sessions attach to it instead: maybe_probe_default_daemon_socket (tui/src/lib.rs:461), app_server_target_for_launch (:929-956, the LocalDaemon arm at :948-954), can_reuse_implicit_local_daemon (:990-1001). If the socket is missing or the handshake fails, that session silently falls back to embedded (lib.rs:520-525).
That daemon is a separate, console-less process: it is launched with DETACHED_PROCESS | CREATE_BREAKAWAY_FROM_JOB and all three stdio streams detached (app-server-daemon/src/backend/pid_start.rs:91-95 and :207). It is started by codex agents (cli/src/main.rs:2735-2747) or from inside the TUI.
So the same tool call behaves differently depending on which session runs it:
child of the TUI process → inherits that tab's console → invisible;
child of the detached daemon → there is no console to inherit, so Windows allocates a new one for any console-subsystem child spawned without CREATE_NO_WINDOW → visible window. With Windows Terminal as the default terminal host that is a new terminal window, which is exactly what your screenshot shows.
The parent executable is the same codex.exe in both cases; only its console state differs. This is not hypothetical in this repo: the identical spawn was already observed and shim-validated on Windows in #37599 — codex-code-mode-host.exe (PE subsystem 3) is started by code-mode/src/remote_session/connection.rs:156-169, which pipes stdio and sets no Windows creation flags, and a CREATE_NO_WINDOW shim removed the window with the protocol unchanged. That report is still accurate on current main (:157), and it is the non-ephemeral window you saw.
Sites that spawn a console-subsystem child without that flag (fixing only one of them leaves the rest flashing):
utils/pty/src/win/job.rs:125-126prepare_suspended_spawn — sets only CREATE_SUSPENDED; shared by the hooks runner (hooks/src/engine/command_runner.rs:237), the git helper (git-utils/src/git_process.rs:45), and both MCP launchers (rmcp-client/src/stdio_server_launcher.rs:299, rmcp-client/src/http_headers.rs:467). CREATE_NO_WINDOW | CREATE_SUSPENDED is already used in-tree (windows-sandbox-rs/src/setup_launch.rs:30).
utils/pty/src/pipe.rs:192 — a plain command.spawn() with no creation_flags at all. This is the route ordinary agent shell commands take: the tool's tty defaults to false (core/src/tools/handlers/unified_exec.rs:70-72) → sandboxing/src/spawn.rs:122/:132.
app-server-daemon/src/backend/pid_start.rs:103 — the app-server --managed-daemon --help capability probe, also a console-subsystem child with null stdio and no flag.
The repo already treats this as a requirement for its own daemon-side helpers: app-server-daemon/src/managed_install.rs:79/:106, app-server-daemon/src/update_loop.rs:448 (powershell.exe), and the elevated sandbox maps it deliberately (windows-sandbox-rs/src/process.rs:109-114 — CREATE_NO_WINDOW only when stdio is supplied and the mode is NoWindow).
Cheap checks that separate this from a generic terminal-settings theory, run in the session that pops windows:
/status — this hypothesis predicts a background-service row (unix://…codex.sock; tui/src/status/remote_connection.rs:19-43 → status/card.rs:832-838), and none in the first session.
Parent PID of one popped window's child (Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,Name) — the predicted parent is a standalone codex.exe app-server --listen unix:// … process (app-server-daemon/src/backend/pid.rs:354-363), not the TUI's own PID.
Fresh state: stop the daemon (codex app-server daemon stop; state is visible in codex doctor), start both tabs before any daemon exists → both should be silent; then start the background server (codex agents) and open a new tab → from then on the new tab pops windows.
If those three hold, this is the daemon's child-spawn flags rather than terminal configuration. I can prepare a patch plus a Windows-only assertion that no console is allocated for the freshly spawned child — but I cannot exercise the Windows path from my side, so your read-back on those checks would be worth more than my guess.
Activity
rbleattler commentedon Sep 11, 2026
Additional reproduction detail: one child process spawned by the secondary Codex session was not ephemeral. A separate visible window remained open while running:
This makes the issue look less like generic short-lived shell flashing and more like the secondary session is causing Codex child/host processes themselves to be launched into separate visible console windows. The behavior is still specific to the second concurrent Codex tab/session; the primary session does not do this.
github-actions commentedon Sep 11, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
argszero commentedon Sep 12, 2026
Your differentiator is the whole clue, and it points at the shared app-server daemon. It explains both halves of the symptom, including the non-ephemeral
codex-code-mode-host.exewindow.The two sessions are not running the same server:
AppServerClient::InProcess), i.e. inside the Windows Terminal tab that already owns a console.maybe_probe_default_daemon_socket(tui/src/lib.rs:461),app_server_target_for_launch(:929-956, theLocalDaemonarm at:948-954),can_reuse_implicit_local_daemon(:990-1001). If the socket is missing or the handshake fails, that session silently falls back to embedded (lib.rs:520-525).That daemon is a separate, console-less process: it is launched with
DETACHED_PROCESS | CREATE_BREAKAWAY_FROM_JOBand all three stdio streams detached (app-server-daemon/src/backend/pid_start.rs:91-95and:207). It is started bycodex agents(cli/src/main.rs:2735-2747) or from inside the TUI.So the same tool call behaves differently depending on which session runs it:
CREATE_NO_WINDOW→ visible window. With Windows Terminal as the default terminal host that is a new terminal window, which is exactly what your screenshot shows.The parent executable is the same
codex.exein both cases; only its console state differs. This is not hypothetical in this repo: the identical spawn was already observed and shim-validated on Windows in #37599 —codex-code-mode-host.exe(PE subsystem 3) is started bycode-mode/src/remote_session/connection.rs:156-169, which pipes stdio and sets no Windows creation flags, and aCREATE_NO_WINDOWshim removed the window with the protocol unchanged. That report is still accurate on currentmain(:157), and it is the non-ephemeral window you saw.Sites that spawn a console-subsystem child without that flag (fixing only one of them leaves the rest flashing):
utils/pty/src/win/job.rs:125-126prepare_suspended_spawn— sets onlyCREATE_SUSPENDED; shared by the hooks runner (hooks/src/engine/command_runner.rs:237), the git helper (git-utils/src/git_process.rs:45), and both MCP launchers (rmcp-client/src/stdio_server_launcher.rs:299,rmcp-client/src/http_headers.rs:467).CREATE_NO_WINDOW | CREATE_SUSPENDEDis already used in-tree (windows-sandbox-rs/src/setup_launch.rs:30).utils/pty/src/pipe.rs:192— a plaincommand.spawn()with nocreation_flagsat all. This is the route ordinary agent shell commands take: the tool'sttydefaults tofalse(core/src/tools/handlers/unified_exec.rs:70-72) →sandboxing/src/spawn.rs:122/:132.code-mode/src/remote_session/connection.rs:157— the code-mode host (item 1 of Windows: codex-code-mode-host opens a visible Windows Terminal window #37599).app-server-daemon/src/backend/pid_start.rs:103— theapp-server --managed-daemon --helpcapability probe, also a console-subsystem child with null stdio and no flag.The repo already treats this as a requirement for its own daemon-side helpers:
app-server-daemon/src/managed_install.rs:79/:106,app-server-daemon/src/update_loop.rs:448(powershell.exe), and the elevated sandbox maps it deliberately (windows-sandbox-rs/src/process.rs:109-114—CREATE_NO_WINDOWonly when stdio is supplied and the mode isNoWindow).Cheap checks that separate this from a generic terminal-settings theory, run in the session that pops windows:
/status— this hypothesis predicts a background-service row (unix://…codex.sock;tui/src/status/remote_connection.rs:19-43→status/card.rs:832-838), and none in the first session.Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,Name) — the predicted parent is a standalonecodex.exe app-server --listen unix:// …process (app-server-daemon/src/backend/pid.rs:354-363), not the TUI's own PID.codex app-server daemon stop; state is visible incodex doctor), start both tabs before any daemon exists → both should be silent; then start the background server (codex agents) and open a new tab → from then on the new tab pops windows.If those three hold, this is the daemon's child-spawn flags rather than terminal configuration. I can prepare a patch plus a Windows-only assertion that no console is allocated for the freshly spawned child — but I cannot exercise the Windows path from my side, so your read-back on those checks would be worth more than my guess.