Skip to content

fix(cli): fall back to PollSelector when kqueue can't register stdin (macOS 26+)#12111

Closed
evanstinger wants to merge 1 commit into
NousResearch:mainfrom
evanstinger:fix/macos-26-kqueue-stdin
Closed

fix(cli): fall back to PollSelector when kqueue can't register stdin (macOS 26+)#12111
evanstinger wants to merge 1 commit into
NousResearch:mainfrom
evanstinger:fix/macos-26-kqueue-stdin

Conversation

@evanstinger
Copy link
Copy Markdown

What does this PR do?

Fixes a crash on macOS 26+ where hermes (interactive chat mode) fails immediately with:

OSError: [Errno 22] Invalid argument
  ...
  selectors.py, line 523, in register
    self._selector.control([kev], 0, 0)

macOS 26 introduced a kqueue regression where registering stdin (fd 0) for EVENT_READ raises OSError [Errno 22] Invalid argument. prompt_toolkit triggers this via loop.add_reader(0, ...) in Vt100Input._attached_input().

Root Cause

Python's selectors.KqueueSelector (default on macOS) can no longer register fd 0 on macOS 26+. The existing workaround from #8560 (fstat guard + exception handler) doesn't prevent this crash because the OSError fires inside prompt_toolkit's context manager __enter__, before our exception handler is reached.

Fix

Probe kqueue early in startup (after _apply_profile_override(), before any prompt_toolkit import). If KqueueSelector can't register stdin, replace selectors.DefaultSelector with PollSelector, which works correctly.

Only activates on sys.platform == "darwin" when kqueue is actually broken — zero impact on other platforms or older macOS versions.

Related Issue

Type of Change

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

Changes Made

  • hermes_cli/main.py: Add kqueue probe + PollSelector fallback after _apply_profile_override(), before any prompt_toolkit import

How to Test

  1. On macOS 26+: Run hermes — previously crashed with OSError [Errno 22], now starts normally
  2. On older macOS / Linux: No behavior change — kqueue probe passes, no fallback triggered
  3. Verify the probe: python -c "import selectors; s=selectors.DefaultSelector(); s.register(0, selectors.EVENT_READ); s.unregister(0)" — fails on macOS 26+ with KqueueSelector, passes with PollSelector

Checklist

Code

  • My commit messages follow Conventional Commits
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've tested on my platform: macOS 26.4.1 (Tahoe, Apple Silicon M4 Pro)

Documentation & Housekeeping

  • N/A — no config keys, architecture changes, or tool behavior changes

…(macOS 26+)

macOS 26 introduced a kqueue regression where registering stdin (fd 0)
for EVENT_READ raises OSError [Errno 22] Invalid argument. This crashes
prompt_toolkit on startup via Vt100Input._attached_input() →
loop.add_reader(0, ...).

Detect the broken kqueue early in startup (before prompt_toolkit is
imported) and replace selectors.DefaultSelector with PollSelector.

Upstream issue: prompt-toolkit/python-prompt-toolkit#1943
Upstream PR (unmerged): prompt-toolkit/python-prompt-toolkit#2065
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard area/config Config system, migrations, profiles labels Apr 23, 2026
@teknium1
Copy link
Copy Markdown
Contributor

Closing — superseded by #26077 (merged as commit d3d5916), which preventively probes kqueue at startup and falls back to SelectSelector when fd 0 cannot be registered. The widened except-clause matching EINVAL / EBADF / 'Invalid argument' — which most PRs in this cluster including yours added — is also included.

Thanks for the fix; closing as duplicate of the merged work.

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

Labels

area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard 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.

3 participants