Skip to content

fix(windows): add CREATE_BREAKAWAY_FROM_JOB to windows_hide_flags() - #55753

Closed
ms-alan wants to merge 1 commit into
NousResearch:mainfrom
ms-alan:fix/55604-windows-hide-flags
Closed

fix(windows): add CREATE_BREAKAWAY_FROM_JOB to windows_hide_flags()#55753
ms-alan wants to merge 1 commit into
NousResearch:mainfrom
ms-alan:fix/55604-windows-hide-flags

Conversation

@ms-alan

@ms-alan ms-alan commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Closes #55604

Summary

windows_hide_flags() was returning only _CREATE_NO_WINDOW, missing _CREATE_BREAKAWAY_FROM_JOB which is already used by windows_detach_flags() for the same reason: Electron and Tauri desktop apps wrap their subprocesses in job objects, and without the breakaway flag a child process (e.g. cmd.exe windows flash) can be killed when the parent Electron/Tauri process exits.

Root cause

CREATE_BREAKAWAY_FROM_JOB (0x01000000) already exists at line 110 of _subprocess_compat.py and is used by windows_detach_flags(). It was simply missing from windows_hide_flags().

Fix

Added _CREATE_BREAKAWAY_FROM_JOB to windows_hide_flags():

Note: DETACHED_PROCESS is intentionally not added — windows_hide_flags() is for short-lived synchronous children where stdout capture is needed, and DETACHED_PROCESS would sever stdio.

Related

Closes NousResearch#55604

windows_hide_flags() was returning only _CREATE_NO_WINDOW, missing
_CREATE_BREAKAWAY_FROM_JOB which is already used by windows_detach_flags()
for the same reason: Electron and Tauri desktop apps wrap their
subprocesses in job objects, and without the breakaway flag a child
process (e.g. cmd.exe windows flash) can be killed when the parent
Electron/Tauri process exits.

Note: DETACHED_PROCESS is intentionally NOT added — windows_hide_flags()
is for short-lived synchronous children where stdout capture is needed.
@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows P2 Medium — degraded but workaround exists duplicate This issue or pull request already exists labels Jun 30, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #55613 — identical core change (return _CREATE_NO_WINDOW | _CREATE_BREAKAWAY_FROM_JOB in windows_hide_flags(), hermes_cli/_subprocess_compat.py) fixing the same issue #55604. #55613 is canonical: triaged earlier and includes a regression test (test_windows_hide_flags_includes_breakaway_from_job); this PR is the one-line change with only a longer comment, no test. Related to the other identical OPEN twins #55667 and #55692, and to issue #55604.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracing the existing breakaway constant and keeping DETACHED_PROCESS out of the synchronous path.

Problems

  • hermes_cli/_subprocess_compat.py:138-144 documents that CREATE_BREAKAWAY_FROM_JOB can cause ERROR_ACCESS_DENIED / PermissionError when the parent job rejects breakaway. This change adds that bit to every windows_hide_flags() consumer, but generic callers such as tools/environments/base.py:145-153 pass the result directly to subprocess.Popen without the documented retry-without-breakaway path.
  • The PR has no regression test for the changed helper behavior. The linked canonical duplicate, #55613, includes a helper-level test.

Suggested changes

  • Scope breakaway to spawns that actually need to outlive the parent job, or provide and test a safe fallback for hide-only callers before changing the shared helper.
  • Add a focused simulated-Windows regression test for the final behavior.

Automated hermes-sweeper review.

# objects, and without breakaway a child started with capture_output=True
# can be killed when the parent Electron/Tauri process exits — even though
# DETACHED_PROCESS is not set and stdio is still connected.
return _CREATE_NO_WINDOW | _CREATE_BREAKAWAY_FROM_JOB

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CREATE_BREAKAWAY_FROM_JOB can make CreateProcess fail when the parent job disallows breakaway; current main documents this at hermes_cli/_subprocess_compat.py:138-144. Because this helper is used by synchronous callers without an OSError retry (for example tools/environments/base.py:145-153), please avoid applying this bit globally unless the fallback is designed and covered.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Closing after the class-level fix in PR #70205 (merged as 0dbf639) — the premise here doesn't hold against Win32 semantics, and the underlying symptom is addressed at a different layer.

Two problems with adding CREATE_BREAKAWAY_FROM_JOB to windows_hide_flags():

  1. Job objects don't affect console/window creation. CREATE_NO_WINDOW is not "silently ignored inside a job object" — jobs govern process lifetime and limits, not console allocation. The flag that actually neutralizes CREATE_NO_WINDOW is DETACHED_PROCESS (documented in the Process Creation Flags spec), and the real cause of the Electron/desktop flashes was the parent being console-less (GUI-subsystem pythonw.exe / DETACHED daemons), so every console-subsystem child had to allocate its own visible console. That's fixed at the root: commit aa2ae36 launches the desktop backend as hidden-console python, and fix(windows): hidden-console daemons — extend the parent-console flash fix to every detached spawn path #70205 extends the same to all detached daemon paths.

  2. Breakaway on every short-lived spawn is harmful. windows_hide_flags() feeds ~40 synchronous capture-output call sites. In a job that doesn't set JOB_OBJECT_LIMIT_BREAKAWAY_OK, CREATE_BREAKAWAY_FROM_JOB makes CreateProcess fail with ERROR_ACCESS_DENIED — and none of those sites have a retry, so probes and helpers would start crashing in restrictive Windows Terminal/container/kiosk configs. Short-lived children being torn down with the parent's job is also the desired behavior for helpers.

If a flash persists at a specific spawn site on current main, that's worth a fresh issue with the process name from the flash — it would point at a leg the parent-console fix doesn't cover. Thanks for digging into the Windows spawn behavior.

@teknium1 teknium1 closed this Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

windows_hide_flags() missing CREATE_BREAKAWAY_FROM_JOB — cmd.exe windows flash in Electron desktop apps (Hermes One, etc.)

3 participants