Skip to content

fix(cron): close codex app-server session in teardown to prevent subprocess leak (#62101) - #62105

Open
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-62101
Open

fix(cron): close codex app-server session in teardown to prevent subprocess leak (#62101)#62105
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-62101

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes a subprocess leak in cron jobs when using the codex_app_server runtime. Each scheduled cron run creates a new ephemeral agent, which spawns a codex app-server subprocess. The subprocess should be cleaned up when the job finishes, but agent.close() does not include _codex_session cleanup. This caused one leaked codex app-server subprocess per cron run until the gateway is restarted.

The fix adds a close_codex_session() helper in agent/codex_runtime.py (idempotent, safe to call multiple times) and calls it from cron's _teardown_cron_agent() function in the finally block after agent.close().

Related Issue

Fixes #62101

Type of Change

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

Changes Made

  • agent/codex_runtime.py: Add close_codex_session() helper function that safely closes the Codex app-server session if it exists
  • cron/scheduler.py: Call close_codex_session() in _teardown_cron_agent() after agent.close() to prevent subprocess leaks

How to Test

  1. Configure provider: openai-codex with openai_runtime: codex_app_server
  2. Create a recurring cron job: hermes cron create "0 8,13,18 * * *" "echo test"
  3. Start the gateway: hermes gateway --platform telegram
  4. Wait for a few scheduled runs to complete
  5. Check for leaked codex app-server processes: ps -axo pid,ppid,lstart,command | grep "codex app-server"
  6. Expected result: No codex app-server subprocesses remain after each cron job completes

Observed result: The issue reporter verified locally that after this patch, a manual hermes cron run leaves no codex app-server process behind once the job completes.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • 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 run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 26.5 (arm64)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

…rocess leak (NousResearch#62101)

Ephemeral cron agents leak the codex app-server subprocess because
agent.close() does not cleanup _codex_session. This adds a cleanup
helper in codex_runtime.py and calls it from cron's _teardown_cron_agent().
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management codex P3 Low — cosmetic, nice to have labels Jul 10, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused cron cleanup. The premise is confirmed on current main: agent/codex_runtime.py:325 creates a per-agent app-server session, while cron/scheduler.py:3372-3385 tears down cron agents through agent.close() without closing that session.

Problems

  • The diff at 7313d61c62a2 changes only agent/codex_runtime.py and cron/scheduler.py; it adds no regression test. Existing teardown-order coverage in tests/cron/test_run_one_job.py:165-205 verifies delivery before agent.close() but does not exercise a Codex session.

Suggested changes

  • Add a cron teardown regression that asserts _teardown_cron_agent() closes and clears an attached _codex_session, including when agent.close() raises. This validates the exact lifecycle path changed here.

Automated hermes-sweeper review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history codex comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: cron jobs leak one codex app-server subprocess per run inside the gateway (codex_app_server runtime)

3 participants