get2knowio / get2knowio/airframe
Investigate openai-codex-sdk subprocess transport leak on failed runs
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
When ``CodexRuntime`` raises any exception during ``execute()`` (e.g.
``RuntimeModelNotFoundError`` on a wrong model, ``RuntimeAuthError``,
schema validation failure), the user sees the correct exit code and
error message — but Python prints trailing noise from a subprocess
transport that wasn't cleaned up before ``asyncio.run()`` closed the
loop:
\`\`\`
Exception ignored in:
RuntimeError: Event loop is closed
Task was destroyed but it is pending!
\`\`\`
## Where the bug lives
Inside ``openai-codex-sdk`` — specifically the ``Thread.run()`` failure
path. The SDK spawns a ``codex exec`` subprocess (tracked by a Python
``BaseSubprocessTransport``) but doesn't await its shutdown when the
turn raises. Python's garbage collector then runs the transport's
``__del__`` after the asyncio loop is closed.
Airframe's ``CodexAgentSession.close()`` already does the right thing on
its side (``controller.abort()`` + reference drop), but the transport
lives inside the SDK's ``Thread`` object — out of reach.
## Why this isn't blocking
- Exit code is correct (1 on failure).
- Structured error + hint print before the noise.
- Only happens on failed runs (successful round-trips are clean).
- Nothing leaks across the Python process boundary; the OS reaps the
subprocess when the script exits.
## What to do
1. Reproduce against ``openai-codex-sdk`` directly (minimal repro
outside airframe).
2. File upstream issue with the repro.
3. Optionally add a workaround in ``airframe.adapters.codex`` if upstream
doesn't move — e.g. weakly-track spawned transports and call
``transport.close()`` explicitly in ``runtime.close()``. Weigh
workaround complexity against living with the warning.
## Reproduction
Any failed ``CodexRuntime`` call shows it. Easiest path:
\`\`\`bash
unset AIRFRAME_PROBE_MODEL_CODEX OPENAI_API_KEY
# requires ChatGPT-account auth via `codex login`
uv run python examples/probe_codex.py
\`\`\`
The probe will raise ``RuntimeModelNotFoundError`` (since ``gpt-5-codex``
isn't served under ChatGPT-account auth), and you'll see the trailing
``Event loop is closed`` exception ignored by the GC.
Contributor guide
Research direction
Run the minimal reproduction in examples/probe_codex.py, then reproduce the failure directly against openai-codex-sdk. Inspect the Thread.run() failure path and Airframe's CodexAgentSession.close() or runtime.close() behavior. Done means an upstream issue is filed with the reproduction, or a justified workaround is added in airframe.adapters.codex.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100