openai / openai/codex

[code-mode] `exec` results honour the script's `max_output_tokens` with no upper bound — one 497 KB shell result reached the model as ~138K tokens (function mode clamps to the model's truncation policy)

Open
#42,367 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

azure bug CLI context performance tool-calls
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

codex-cli 0.137.0-alpha.4 (app-server, driven through the openai-codex Python SDK 0.1.0b3). The same code is on main today.

Which model were you using?

gpt-5.6-luna (Azure OpenAI deployment; the catalog resolves it to tool_mode: code_mode_only). Also seen with gpt-5.6-terra.

What issue are you seeing?

In code mode, the size of a tool result the model receives is bounded only by what the model itself asked for:

  • codex-rs/core/src/tools/code_mode/mod.rstruncate_code_mode_result uses resolve_max_tokens(max_output_tokens), i.e. the // @exec: {"max_output_tokens": N} pragma value (or 10 000 when absent), with no clamp;
  • codex-rs/core/src/tools/context.rs — the function-mode path ExecCommandToolOutput::model_output_max_tokens does clamp: resolve_max_tokens(self.max_output_tokens).min(self.truncation_policy.token_budget());
  • codex-rs/code-mode/src/description.rs only checks the pragma is a non-negative safe integer.

So a script that raises the pragma passes a raw shell result of any size (up to the 1 MiB UNIFIED_EXEC_OUTPUT_MAX_BYTES buffer) straight into the context. Observed in an automated evaluation run (2026-09-02): an rg … | head -240 over a repository returned 496 887 bytes in 57 very long lines; the next model request carried 159 055 uncached input tokens (≈138K of them that tool result) and took 1 113 s to be answered against the Azure deployment (the same request shape on 2026-08-31, without a raised budget, was cut to ~10K tokens and answered in 2 s). Across ~680 shell results ≥100 KB in the same evaluation archive (gpt-5.6 models), exactly two reached the model uncut — so this is rare, but when it happens it costs a turn's worth of time and tokens and the harness has no knob: tool_output_token_limit only rewrites model.truncation_policy, which the code-mode result path never reads; the catalog's tool_mode overrides features.code_mode* (session/turn_context.rs), so the harness cannot leave code mode either.

Related but the inverse framing: #33402 (outer exec truncates below nested budgets). This report is about the upper direction.

Expected

Code-mode exec/wait results are clamped the way function-mode results already are — min(requested, truncation_policy.token_budget()) (or a configurable ceiling) — so a model cannot request more tool output than the model's own output policy allows.

Steps to reproduce
  1. Any code-mode model (catalog tool_mode: code_mode_only, e.g. gpt-5.6-*).
  2. Have the model run an exec script whose first line is // @exec: {"max_output_tokens": 200000} and whose body calls exec_command({ cmd: "yes 'x…(8 KB line)' | head -60" }) and text(result.output).
  3. In the rollout JSONL, the custom_tool_call_output carries the full ~480 KB; the next request's input_tokens grows by ~130K.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in codex-rs/core/src/tools/code_mode/mod.rs at truncate_code_mode_result, then compare its resolve_max_tokens handling with ExecCommandToolOutput::model_output_max_tokens in codex-rs/core/src/tools/context.rs and the pragma validation in codex-rs/code-mode/src/description.rs. Done means code-mode exec and wait results apply the truncation policy ceiling to the requested max_output_tokens, preventing oversized results from reaching the model.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.