Summary
When file descriptors are exhausted (EMFILE / "Too many open files"), Codex can panic in AbsolutePathBuf::parent().
Observed panic:
parent of AbsolutePathBuf must be absolute: Os { code: 24, ... "Too many open files" }
- Followed by:
in-flight tool future failed during drain: ... JoinError::Panic(...)
Why this happens
AbsolutePathBuf::parent() currently does this:
- calls
self.0.parent()
- then re-validates via
Self::from_absolute_path(p).expect(...)
from_absolute_path() uses path_absolutize::absolutize(), and path-absolutize calls std::env::current_dir() even for already-absolute paths.
Under EMFILE, current_dir() fails, so the expect(...) in parent() panics.
Impact
- An otherwise recoverable resource-exhaustion condition is escalated into a process panic.
- This is easiest to hit during high parallelism (many sub-agents/tool tasks).
Repro notes
This was observed with low soft ulimit -n (256) and heavy parallel tool/sub-agent activity.
Proposed fix
In AbsolutePathBuf::parent(), avoid re-absolutizing and avoid expect:
- construct directly from known parent path:
Self(p.to_path_buf())
This preserves the invariant (parent of an absolute path is absolute) and removes the unnecessary current_dir() dependency on the hot path.
I have an isolated PR ready with this change plus tests.
Summary
When file descriptors are exhausted (
EMFILE/ "Too many open files"), Codex can panic inAbsolutePathBuf::parent().Observed panic:
parent of AbsolutePathBuf must be absolute: Os { code: 24, ... "Too many open files" }in-flight tool future failed during drain: ... JoinError::Panic(...)Why this happens
AbsolutePathBuf::parent()currently does this:self.0.parent()Self::from_absolute_path(p).expect(...)from_absolute_path()usespath_absolutize::absolutize(), andpath-absolutizecallsstd::env::current_dir()even for already-absolute paths.Under
EMFILE,current_dir()fails, so theexpect(...)inparent()panics.Impact
Repro notes
This was observed with low soft
ulimit -n(256) and heavy parallel tool/sub-agent activity.Proposed fix
In
AbsolutePathBuf::parent(), avoid re-absolutizing and avoidexpect:Self(p.to_path_buf())This preserves the invariant (parent of an absolute path is absolute) and removes the unnecessary
current_dir()dependency on the hot path.I have an isolated PR ready with this change plus tests.