fix(gateway): survive faulthandler.enable() when sys.stderr is None (#71671 salvage) - #72304
Merged
Conversation
faulthandler.enable() writes to sys.stderr by default, and raises
RuntimeError('sys.stderr is None') when the gateway is launched
without an attached console — e.g. via the Windows Startup VBS shim,
pythonw.exe, a detached service, or any parent that redirects stderr
to DEVNULL. Because this happens on the very first line of
GatewayRunner.start(), the whole gateway used to die at startup and
every configured platform adapter (Discord bot, Telegram, Slack, …)
would silently show offline until the user manually re-ran
'hermes gateway run --replace' from a real terminal.
Wrap the call and fall back to a log-file file descriptor
(logs/gateway_faulthandler.log) when stderr is unavailable, so
fatal-error stack dumps still land somewhere useful. If even the
fallback fails we log-and-continue rather than kill the gateway.
Repro traceback (from a real user's gateway-exit-diag.log, launched
via the Startup VBS with stdin_is_tty=false):
File "gateway/run.py", line 7821, in start
faulthandler.enable()
RuntimeError: sys.stderr is None
Source-regex tests are banned (AGENTS.md 'Never read source code in tests') — keep only the behavioral regression test.
Contributor
૮ >ﻌ< ა ci reviewran on 37c8e67 ℹ️ InfoDesktop E2E visual evidence · View test artifacts · View job1 visual diff. inline evidence upload failed. Failed to upload diff-665a0833239e-onboarding-overlay-diff.png with gh image (exit code 1): Error uploading /home/runner/work/_temp/e2e-evidence/diff-665a0833239e-onboarding-overlay-diff.png: step 0 (get upload token): uploadToken not found on repo page — do you have write access to NousResearch/hermes-agent? (or, if NousResearch enforces SAML SSO, authorize at https://github.com/orgs/NousResearch/sso) |
This was referenced Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Headless Windows gateways no longer die at startup:
faulthandler.enable()on the first line ofGatewayRunner.start()raisesRuntimeError: sys.stderr is Nonewhen the gateway is spawned without a stderr handle (legacy pythonw scheduled tasks, VBS shims, detachedstdio='ignore'spawns), taking every platform adapter offline. Root cause: #70344 added the call unconditionally;faulthandler.enable()writes tosys.stderrby default.Salvages #71671 by @hereicq with authorship preserved. Chosen over the duplicate #72158 (bare skip-guard) because the fallback keeps the #70344 freeze diagnostics working on exactly the headless installs that need them most.
Changes
gateway/run.py: wrapfaulthandler.enable(); onRuntimeError/ValueError/OSErrorfall back toenable(file=logs/gateway_faulthandler.log); if even that fails, log and continue (@hereicq)tests/gateway/test_71671_faulthandler_no_stderr.py: behavioral regression test (@hereicq)gateway/run.pysource text — banned antipattern per AGENTS.md "Never read source code in tests"contributors/emails/: mapping for @hereicqValidation
scripts/run_tests.sh tests/gateway/test_71671_faulthandler_no_stderr.pysys.stderr is None), isolatedHERMES_HOMEenable()raises; guarded path enables via file fallback, dump lands inlogs/gateway_faulthandler.log, exit 0py_compile gateway/run.pySibling audit: all other faulthandler/stderr sites (
gateway/shutdown_watchdog.py, telegram adapter) already wrapped in try/except — run.py:7829 was the only unguarded one.Closes #71671. Closes #72158 (duplicate, 18h later).
Infographic