Skip to content

fix(gateway): set NumberOfFiles limits in macOS launchd plist (#36899) - #36939

Closed
luyao618 wants to merge 1 commit into
NousResearch:mainfrom
luyao618:fix/launchd-plist-nofiles-36899
Closed

fix(gateway): set NumberOfFiles limits in macOS launchd plist (#36899)#36939
luyao618 wants to merge 1 commit into
NousResearch:mainfrom
luyao618:fix/launchd-plist-nofiles-36899

Conversation

@luyao618

@luyao618 luyao618 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #36899.

On macOS, gateway installs as a launchd LaunchAgent inherit a default RLIMIT_NOFILE soft limit (typically 256). Long-running gateway processes eventually exhaust that budget and crash during atomic writes of sessions.json with:

OSError: [Errno 24] Too many open files: '/Users/<user>/.hermes/sessions/.sessions_<random>.tmp'

The generated plist in hermes_cli/gateway.py::generate_launchd_plist() previously did not set any resource limits, so launchd's default applied.

Fix

Embed SoftResourceLimits and HardResourceLimits dicts with NumberOfFiles=65536 in the emitted plist. This matches the verified manual workaround in the issue and is well below macOS's hard ceiling, so it lifts the soft limit without requiring any user intervention. The existing launchd_plist_is_current() drift check will rewrite stale plists on the next hermes gateway install --system.

Verification

  • python -m pytest tests/hermes_cli/test_gateway_service.py -k launchd_plist — passes.
  • New regression test test_launchd_plist_sets_nofiles_resource_limits parses the generated plist and asserts both keys + NumberOfFiles integers are present (verified at 65536 via plistlib.loads).
  • Codex review: APPROVE — plist XML valid, NumberOfFiles is a documented launchd key (see man launchd.plist), no regressions.

Scope

  • hermes_cli/gateway.pygenerate_launchd_plist() (XML insertion only)
  • tests/hermes_cli/test_gateway_service.py — one focused regression test

…search#36899)

The generated LaunchAgent plist did not include SoftResourceLimits or
HardResourceLimits entries. Under launchd, gateway processes inherit a
default RLIMIT_NOFILE soft limit (typically 256), which the long-running
gateway exhausts over time. This surfaces as:

    OSError: [Errno 24] Too many open files:
        '/Users/<user>/.hermes/sessions/.sessions_<random>.tmp'

during atomic writes of sessions.json (and other paths).

Add SoftResourceLimits and HardResourceLimits dicts with
NumberOfFiles=65536 to generate_launchd_plist() so newly installed
LaunchAgents get a sane fd budget out of the box. Existing gateway
installs will pick up the new limits on the next 'hermes gateway install'
(plist-current check will detect drift and rewrite).

Adds a regression test that asserts both keys + the NumberOfFiles
integer are present in the emitted plist.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery comp/cli CLI entry point, hermes_cli/, setup wizard labels Jun 1, 2026
@luyao618 luyao618 closed this Jun 28, 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 comp/gateway Gateway runner, session dispatch, delivery 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.

macOS launchd gateway can hit Errno 24 because generated plist lacks NumberOfFiles limits

2 participants