Codex thread resume can exhaust server heap on large histories
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Area
apps/server
Steps to reproduce
- Use the Codex app-server provider with a long, image-heavy thread whose rollout has grown to hundreds of megabytes or more.
- Restart T3 Code, or otherwise require T3 to resume the provider session from its saved Codex thread id.
- Continue the thread.
- Observe the T3 server while it handles
thread/resume.
Expected behavior
T3 resumes the thread from its saved provider id without loading historical turns it does not use. The server remains responsive regardless of the size of the existing Codex rollout.
Actual behavior
T3 sends thread/resume without excludeTurns: true. Codex therefore returns the complete historical thread.turns payload. T3 only reads thread metadata from that response, but Node must first receive and decode the entire JSON document.
On an affected computer-use thread with an approximately 1 GB rollout, this caused repeated server heap exhaustion and restarts. The crash recurred with retained heaps ranging from roughly 810 MB to 2.8 GB, depending on concurrent work and the configured heap ceiling.
Impact
Blocks work completely. Once the history is large enough, the thread cannot be resumed reliably and the T3 backend can restart while unrelated requests are in flight.
Version and environment
- Fork based on upstream
mainat270489b88742 - T3 Code Desktop AppImage on Arch Linux
- Codex CLI 0.146.1, using the Codex app-server protocol
Relevant log excerpt
Mark-Compact (reduce) 810.4 (...) MB ...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Diagnosis
CodexSessionRuntime calls thread/resume and then uses only thread.id, thread.cwd, and thread.model, but the request omits the protocol's existing excludeTurns option. The Codex app-server documentation already defines that option for metadata-only resume responses:
https://github.com/openai/codex/blob/main/codex-rs/app-server/README.md
Suggested fix
- Send
excludeTurns: truefrom the T3 resume path. - Ensure the generated protocol binding encodes the field.
- Add a regression test that verifies resume requests omit historical turns.
I validated this approach locally: the resume path still receives the metadata it needs without materializing the historical turn payload.
Workaround
Starting a fresh thread avoids the oversized resume response. Raising Node's heap limit only delays the failure as the rollout continues to grow.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/server at the CodexSessionRuntime resume path, then read the Codex app-server README section describing the excludeTurns option. Check the generated protocol binding and the existing resume-related tests. Done means resume requests encode excludeTurns: true, preserve the needed thread metadata, and have a regression test confirming historical turns are not requested.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100