[Windows] Visible console window per render shot: 0.8.44 resolves @puppeteer/browsers 3.2.1, where detached defeats windowsHide (fixed upstream in 3.2.2)
Summary
On Windows, every hyperframes render opens a visible console window per browser launch (78 shots = 78 windows), stealing focus and making the machine unusable for anything else during a render.
This is not one of the windowsHide gaps already tracked in #3476 / #3500 / #3851 / #3960 / #3996 — those all cover hyperframes' own spawns. This one comes from @puppeteer/browsers, and it is already fixed upstream. 0.8.44 just resolves to the one broken version.
Root cause
[email protected] declares "puppeteer-core": "^25.8.0". In practice that resolved here to [email protected] → @puppeteer/[email protected].
@puppeteer/[email protected] lib/launch.js spawns the browser with both flags:
opts.detached ??= true; // line 157
...
childProcess.spawn(this.#executablePath, this.#args, {
detached: opts.detached, // line 173
windowsHide: true, // line 174
...
});On Windows libuv ORs DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP (from detached) together with CREATE_NO_WINDOW (from windowsHide) into the CreateProcessW creation flags. Those are mutually exclusive: DETACHED_PROCESS wins, the child inherits no console, and chrome-headless-shell.exe — a console-subsystem binary (IMAGE_SUBSYSTEM_WINDOWS_CUI) — gets a freshly allocated, visible console. windowsHide: true is dead code in that combination.
Upstream: puppeteer/puppeteer#15410, introduced by #15339, reverted by #15415, released in @puppeteer/[email protected].
Evidence
Controlled A/B on the same binary, same machine, only detached differs. External EnumWindows + IsWindowVisible monitor sampling at 25 ms:
MODE=detached ({detached:true, windowsHide:true}) browser procs=4 NEW visible windows=1 <- class=ConsoleWindowClass proc=chrome-headless-shell
MODE=hidden ({detached:false, windowsHide:true}) browser procs=4 NEW visible windows=0Live capture during an actual hyperframes render, before any workaround:
class=CASCADIA_HOSTING_WINDOW_CLASS proc=WindowsTerminal
class=PseudoConsoleWindow proc=chrome-headless-shell
class=CASCADIA_HOSTING_WINDOW_CLASS proc=WindowsTerminal
class=PseudoConsoleWindow proc=chrome-headless-shell(There is a second, independent aggravating factor worth knowing about: when Windows' Default terminal application is Windows Terminal — the Windows 11 default — the console handoff ignores CREATE_NO_WINDOW entirely, so console children pop a real Windows Terminal window even where windowsHide is correctly set. Switching to Console Host removes that layer; the @puppeteer/browsers bug above survives the switch and still produces ConsoleWindowClass windows.)
Environment
- Windows 11 Pro 26200, Node 24
[email protected],[email protected],@puppeteer/[email protected]- Reproduced via
hyperframes render --quality highandhyperframes snapshot
Suggested fix
Require puppeteer-core >= 25.10.0 (the first release that pulls @puppeteer/[email protected]). ^25.8.0 silently permits the one broken version. #3933 already bumps @puppeteer/browsers to 3.2.2 — this is the reason it matters on Windows.
Workaround for anyone hitting this now
Patch the resolved copy in the npx cache, @puppeteer/browsers/lib/launch.js:
- opts.detached ??= true;
+ opts.detached ??= process.platform !== 'win32';Verified: renders run with zero new visible windows afterwards.
Source: heygen-com/hyperframes