Windows: hide command-safety PowerShell parser process to avoid pwsh.exe console flashes
Summary
On Windows, @openai/codex 0.122.0 (native codex.exe) spawns a command-safety PowerShell parser process as:
pwsh.exe -NoLogo -NoProfile -NonInteractive -EncodedCommand <...>
When codex.exe itself is launched hidden by a parent process, the descendant pwsh.exe still briefly flashes a visible console window. This appears to be because the PowerShell parser child process is spawned without Windows hide/no-window creation flags.
Evidence
Captured on Windows 11 on 2026-04-22 while running TORQUE factory Codex tasks:
torque-server (node.exe, windowsHide:true)
└── codex.exe (spawned directly, not through codex.cmd / node wrapper)
└── pwsh.exe -NoLogo -NoProfile -NonInteractive -EncodedCommand <...>
The parent windowsHide:true is applied to codex.exe. The pwsh.exe descendant still flashes a visible console. We already bypassed the npm/node wrapper (@openai/codex/bin/codex.js) and spawn the bundled native binary directly; the remaining visible window is from the native binary's own child process.
Likely call site
In the current upstream tree, the command-safety parser process is started in:
codex-rs/shell-command/src/command_safety/powershell_parser.rs
Specifically, PowershellParserProcess::spawn() builds:
let mut child = Command::new(executable)
.args([
"-NoLogo",
"-NoProfile",
"-NonInteractive",
"-EncodedCommand",
encoded_parser_script(),
])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn()?;
I do not see a Windows-specific creation_flags() call on this Command before .spawn().
Suggested fix
On Windows, apply CREATE_NO_WINDOW to the PowerShell parser child process:
#[cfg(windows)]
use std::os::windows::process::CommandExt;
#[cfg(windows)]
const CREATE_NO_WINDOW: u32 = 0x08000000;
let mut command = Command::new(executable);
command
.args([
"-NoLogo",
"-NoProfile",
"-NonInteractive",
"-EncodedCommand",
encoded_parser_script(),
])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::null());
#[cfg(windows)]
command.creation_flags(CREATE_NO_WINDOW);
let mut child = command.spawn()?;
An equivalent STARTF_USESHOWWINDOW + SW_HIDE setup would also work, but CREATE_NO_WINDOW is the simplest fit for a non-interactive helper process.
Reproducer
- On Windows 11, install
@openai/codex@0.122.0. - From a parent process, spawn the native bundled
codex.exewith hidden-window semantics. For example, Nodechild_process.spawn(..., { windowsHide: true }). - Run several Codex tasks that trigger shell command-safety checks.
- Observe that
pwsh.exe -NoLogo -NoProfile -NonInteractive -EncodedCommand <...>children appear in the process tree and briefly flash visible console windows.
Expected: the parser pwsh.exe children still run, but no visible console window appears, even briefly.
Actual: a visible PowerShell console flashes for the parser child despite the parent being hidden.
Notes
This is not a request to change the npm wrapper. The wrapper has already been bypassed in the reproducer. The requested fix is in the Rust/native binary's PowerShell parser spawn path.
9 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I'm also affected by this issue on Windows 11 with Codex Desktop (v26.601.2237.0).
Every time Codex executes a shell command, a PowerShell console window briefly flashes on screen (appears and disappears within a second). This is very disruptive during work.
Environment:
The pwsh.exe child processes are spawned with -NoProfile -NonInteractive but without CREATE_NO_WINDOW, causing the visible console flash.
Would appreciate if this could be prioritized as it significantly impacts the user experience on Windows.
Reproduced on Codex Desktop for Windows (Store package 26.707.3563.0). I prepared the minimal upstream fix on a public fork: https://github.com/ryanquadrel/codex/commit/acc2ab3b6c58b5c3d07ccd096d42dfb181d00283 . It applies CREATE_NO_WINDOW to the non-interactive PowerShell parser child while preserving piped stdio. Cross-fork PR creation is currently rejected by the repository API, so this links the ready-to-cherry-pick commit directly.
Reproduced on a newer Codex Desktop for Windows build, with the persistent-window variant shown in this issue.
Environment:
OpenAI.Codex_26.707.9564.0_x64__2p2nqsd0c76g0Microsoft Windows NT 10.0.26200.0 x64Live process inspection showed this chain:
Decoding the PowerShell payload confirms that it begins:
The PowerShell child remains alive rather than being a short transient probe, matching the duration of the user-visible symptom. Correction/clarification: the visible surface is not a conventional black console window. As shown in the screenshots below, it is a completely blank dark-grey window with rounded corners, no title bar, no terminal text, and no visible minimize/maximize/close controls. It remains on the desktop until the associated process ends.
A
conhost.exechild is also present in the packaged app-server process tree. The process evidence strongly associates the behavior with this Codex helper path, but the exact HWND owner was not captured while the blank window was present, so the visible surface should not be overclassified as a standard console window.This is still reproducible on
26.707.9564.0, newer than the26.707.3563.0confirmation above. The linkedCREATE_NO_WINDOWchange still appears directly applicable to this long-lived parser path.I also observed the separate short-lived Desktop process-snapshot PowerShell commands (
Get-CimInstance Win32_Process/Win32_PerfFormattedData_PerfProc_Process), which are tracked more directly in #26613.<img width="739" height="478" alt="Blank dark-grey rounded window behind Codex" src="https://github.com/user-attachments/assets/92c27b27-5585-4602-be59-34a9c41b45c6" />
<img width="420" height="319" alt="Close-up of blank dark-grey rounded window without controls" src="https://github.com/user-attachments/assets/3b46b880-2ff5-465e-852c-3c7786c57271" />
The packaged Windows desktop topology is still relevant on newer builds: local inspection of
26.707.12708.0showed theChatGPT.exe -> codex.exebackend path with long-lived PowerShell/conhost helpers. That is compatible with the persistent blank-window variant described here, although a local guard cannot prove the exact HWND owner after the fact.For users who need a reversible desktop-side mitigation while waiting for the native fix, I maintain:
https://github.com/rwang23/codex-windows-console-guard
Its latest guard recognizes the packaged Codex backend and known console helpers beneath
ChatGPT.exe, in addition to the Git/CMD/PowerShell paths. It hides only matched windows and writes a bounded diagnostic log; it does not change the underlying parser process or claim to fix its lifecycle.The proposed upstream
CREATE_NO_WINDOWchange remains the correct root fix for this non-interactive parser path. A window-hiding guard is only a compatibility fallback for already shipped desktop builds.Confirmation / forensic update (2026-08-06)
Still reproducing on current Windows ChatGPT/Codex desktop app-server.
Environment
OpenAI.CodexMicrosoft Store / WindowsAppsC:\Program Files\WindowsApps\OpenAI.Codex_...\app\resources\codex.exe@openai/codex0.146.0 vendorcodex.exe(same AST payload string; also lacksCREATE_NO_WINDOWstring)Process tree (live)
Decoded payload header (exact):
Binary inspection
Scanned installed
codex.exe(Store 26.730.7989.0, ~347 MB):Long-lived PowerShell AST parser...,command-safety,powershell.exe,-WindowStyle/Hidden(appears only in agent guidance text, not as process spawn flags)CREATE_NO_WINDOW,SW_HIDE,STARTF_USESHOWWINDOW,CREATE_NEW_CONSOLEstring markersSo the child is still being spawned without Win32 no-window creation flags.
-WindowStyle Hiddenis not applied to this long-lived AST helper (or is insufficient alone when the parent is a console-capable process).Symptom for users
Visible PowerShell console open/close flashes while Codex app-server is running in the background — even when the user is typing in a different app (e.g. Hermes CLI). It is easy to mis-attribute to keystrokes; the correlation is Codex tool/command-safety activity / helper lifetime, not the other app's input.
Requested fix
Spawn the AST helper with:
CREATE_NO_WINDOW(0x08000000), and/orSTARTF_USESHOWWINDOW+SW_HIDE, and/orpowershell.exe -WindowStyle Hiddenon the argvplus keep stdin/stdout redirected as today. Do not disable command-safety — only hide the console host.
Happy to retest a preview build against 26.730.7989.0.
Controlled measurement + a second window source the parser-only fix won't cover
Reproduced on Windows 11 Pro 26200, Store package
OpenAI.Codex_26.818.3698.0, runtime bundle26.819.11345(PowerShell 7.6.4).Not repeating the root cause — @ryanquadrel's commit and @kivikdigitalgroup's binary inspection already establish it. Three additions.
1. Controlled A/B on the creation flag
Spawning the bundled
pwsh.exefrom a true GUI-subsystem parent (pythonw.exe, no console), using Codex's exact argv shape (piped stdin/stdout, null stderr):Confirms the proposed fix works, and costs only a hidden conhost.
2. Console inheritance — why parent-side
windowsHideis topology-dependentA CUI child inherits a parent's hidden console and allocates nothing. But a GUI parent holds no console to pass down, so every CUI descendant allocates its own. That is exactly the desktop topology:
This may explain why the original report's
windowsHide: trueoncodex.exedid not stop the descendant flash, while other topologies appear unaffected.3.
codex.exeallocates its own console tooUnder
ChatGPT.exethis is a separate allocation from the parser's. PatchingPowershellParserProcess::spawn()alone is necessary but may not be sufficient for the desktop variant —ChatGPT.exe's spawn ofcodex.exeneeds suppression too, or that console remains. This is a plausible explanation for the persistent blank window variant @BlindsidedGames reported, as distinct from the parser flash.Note for affected desktop users
The desktop app runs
codex.exefrom inside the signed MSIX package (C:\Program Files\WindowsApps\...), which is not user-replaceable. The writable standalone install at%LOCALAPPDATA%\Programs\OpenAI\Codex\binis a different copy the desktop app does not use — so users cannot self-patch the desktop case. Flipping the PE subsystem of the cached helpers is also not a safe workaround: it invalidates the Authenticode signature (verified:Valid→ broken →Validafter restore) and misses the other CUI executables.Only an upstream build fixes the desktop path.
Correction to my previous comment — point 3 was wrong.
I claimed
ChatGPT.exe's spawn ofcodex.exealso needs console suppression. That is incorrect, and I withdraw it.app.asardoes setwindowsHide: trueon the CLI spawn, and I verified on the live process that the resulting console is not visible:So the Desktop side is already doing the right thing, and
PowershellParserProcess::spawn()remains the correct single fix target. Apologies for the noise.Points 1 and 2 stand as measured, and point 2 now sharpens into an open question worth flagging:
conhost +0, windows +0).codex.exedoes have a hidden console here, courtesy ofwindowsHide: true.pwsh.exeparser still produces a visibleCASCADIA_HOSTING_WINDOW_CLASSwindow.So inheritance is not happening for that child. That points at the parser spawn requesting its own console rather than inheriting the parent's — consistent with @kivikdigitalgroup's finding that the binary contains no
CREATE_NO_WINDOW/STARTF_USESHOWWINDOWmarkers, and consistent with the original report that parent-sidewindowsHide: truedid not stop the descendant flash.If that reading is right,
CREATE_NO_WINDOWon the parser spawn (as in @ryanquadrel's commit) is both necessary and sufficient, and no Desktop-side change is required.The user-facing note in my previous comment is unaffected: desktop users cannot self-patch, because the app runs
codex.exefrom the signed MSIX package while the writable standalone install at%LOCALAPPDATA%\Programs\OpenAI\Codex\binis a different copy the app does not use.I prepared and Windows-compiled the minimal fix at https://github.com/jimmylee-cell/codex/commit/0122876924 : apply CommandExt::creation_flags(CREATE_NO_WINDOW) to PowershellParserProcess::spawn. rustfmt --check and cargo check -p codex-shell-command pass on Windows. Cross-fork PR creation is currently rejected for this account, so the public commit is available for cherry-pick/review.