Skip to content

fix(cron): prevent EBADF crash in cron scripts when parent stdin is closed - #40096

Closed
parthchandak02 wants to merge 1 commit into
NousResearch:mainfrom
parthchandak02:fix/cron-ebadf-stdin-devnull
Closed

fix(cron): prevent EBADF crash in cron scripts when parent stdin is closed#40096
parthchandak02 wants to merge 1 commit into
NousResearch:mainfrom
parthchandak02:fix/cron-ebadf-stdin-devnull

Conversation

@parthchandak02

@parthchandak02 parthchandak02 commented Jun 5, 2026

Copy link
Copy Markdown

What does this PR do?

On macOS, long-running Hermes processes may close fd 0 (stdin) during the tool loop. When subprocess.run launches a child Python process, init_sys_streams calls fstat(0), which fails with EBADF → "Fatal Python error: can't initialize sys standard streams".

This adds stdin=subprocess.DEVNULL to _run_job_script() so fd 0 is always valid in the child. The same pattern is already used in gateway/shutdown_forensics.py and tools/process_registry.py (commit 214b953).

Related Issue

No existing issue — discovered locally on macOS 15.5. Root cause is CPython issue #10806 / loky #420.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • cron/scheduler.py: Added stdin=subprocess.DEVNULL to subprocess.run() in _run_job_script()
  • tests/cron/test_cron_script.py: Added test_script_survives_closed_parent_stdin regression test

How to Test

  1. Run python -m pytest tests/cron/ -q — all tests pass
  2. The regression test closes fd 0 in the parent, then calls _run_job_script and verifies the child runs successfully

Checklist

Code

  • My commit message follows Conventional Commits (fix(cron): prevent EBADF crash...)
  • I searched for existing PRs to confirm this isn't a duplicate
  • My PR contains only changes related to this fix
  • I've run python -m pytest tests/cron/ -q and all 389 tests pass
  • I've added tests for my changes (regression test included)
  • I've tested on my platform: macOS 15.5

Documentation & Housekeeping

  • N/A — bug fix, no docs or config changes needed
  • N/A — cross-platform: fix is macOS-specific but the stdin=DEVNULL param is harmless on other platforms

Screenshots / Logs

Test output:

tests/cron/test_cron_script.py::TestRunJobScript::test_script_survives_closed_parent_stdin PASSED
389 passed in 7.23s

…losed

On macOS, long-running Hermes processes may close fd 0 (stdin) during
the tool loop. When the child Python process starts, init_sys_streams
calls fstat(0), which fails with EBADF -> "Fatal Python error: can't
initialize sys standard streams".

Pass stdin=subprocess.DEVNULL so fd 0 is always valid in the child.
This is the same pattern already used in gateway/shutdown_forensics.py
and tools/process_registry.py (commit 214b953).

See CPython issue #10806 / loky #420.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cron Cron scheduler and job management labels Jun 5, 2026
@parthchandak02 parthchandak02 closed this by deleting the head repository Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants