Skip to content

Conversation

@0xRaduan
Copy link
Contributor

@0xRaduan 0xRaduan commented Nov 10, 2025

Problem

The original truncation logic was line-based only. When commands produced few lines with very long content (like cargo build with long paths), the tail containing critical error messages was completely lost.

Additionally, the initial fix introduced a regression where the byte-truncation path didn't enforce line limits. When output exceeded both limits (10KB bytes AND 256 lines), only the byte limit was enforced, allowing thousands of lines to slip through.

Summary

BEFORE PR: Line-based truncation only. Loses tails when lines are long.

AFTER PR: Byte-based head+tail truncation with line limit enforcement. Preserves tails AND respects line limits.

The PR ensures critical error messages at the end of command output (like cargo errors) are always visible to the model, while maintaining the 256-line cap for context efficiency.

Fixes #6415

Changes

Original commit (b38bdae):

  • Modified truncate_formatted_exec_output() to detect when byte truncation is needed upfront
  • When byte truncation occurs, split bytes evenly between head and tail (5KB each) to preserve error messages at the end
  • Line-based truncation still works for outputs with many short lines

Follow-up fix (661d022):

  • Modified truncate_formatted_exec_output() to apply line truncation first when both limits exceeded
  • Account for 3-line marker overhead when calculating head/tail line budgets to ensure output never exceeds 256 lines
  • Removed unused MODEL_FORMAT_HEAD_LINES and MODEL_FORMAT_TAIL_LINES constants
  • Updated test expectations for new omitted line counts

Behavior Change: BEFORE vs AFTER

Scenario 1: Few lines, very long content (e.g., cargo build with long paths)

Input: 5 lines, each ~5KB (total 25KB)

BEFORE PR:

Total output lines: 5

Compiling project v1.0.0 /very/long/path/....[entire first line]
Building dependencies /another/long/....[entire second line]

[... omitted 1 of 5 lines ...]

Warning: unused import /some/path/....[entire fourth line]
error: compilation failed

PROBLEM: Line-based truncation only. First 128 lines kept entirely, regardless of size.
When lines are huge (5KB each), only head lines fit in 10KB budget.
TAIL IS COMPLETELY LOST - error messages invisible to model.

AFTER PR:

Total output lines: 5

Compiling project v1.0.0 /very/long/....[~5KB head content]

[... output truncated to fit 10240 bytes ...]

...path/....[~5KB tail content]
Warning: unused import /some/path/...
error: compilation failed

FIXED: Byte-based truncation splits budget between head AND tail.
Error messages at end are preserved and visible to model.

Scenario 2: Many lines, tiny content (e.g., printing 1-6000)

Input: 6,000 lines of "a\n" (2 bytes each = 12KB total)

BEFORE PR:

Total output lines: 6000

a
a
a
...[126 lines total]

[... omitted 5747 of 6000 lines ...]

a
a
a
...[127 lines total]

Line limit enforced: 256 lines max

AFTER PR:

Total output lines: 6000

a
a
a
...[126 lines total]

[... omitted 5747 of 6000 lines ...]

a
a
a  
...[127 lines total]

Both byte AND line limits enforced: 256 lines max

When commands produce few lines but very long lines (like cargo build),
the previous byte truncation logic only preserved the head, completely
hiding the tail. This caused important error messages at the end of
output to be lost.

Changes:
- Modified truncate_formatted_exec_output() to detect when byte
  truncation is needed upfront
- When byte truncation occurs, split bytes evenly between head and tail
  (5KB each) instead of using line-based slicing
- This ensures error messages at the end (like cargo errors) are visible
- Line-based truncation still works for outputs with many short lines

Added comprehensive tests:
- test_byte_truncation_preserves_tail: Verifies tail preservation with
  cargo-like output (few lines, very long)
- test_line_truncation_still_works: Ensures line truncation unchanged
- test_no_truncation_needed: Validates no truncation for short output

Fixes openai#6415

Signed-off-by: 0xRaduan <[email protected]>
Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@etraut-openai
Copy link
Collaborator

Thanks for the contribution. Before I assign this to a team member for review, please fix the failing tests and respond to the automated code review feedback.

@etraut-openai etraut-openai added the needs-response Additional information is requested label Nov 10, 2025
- Modified truncate_formatted_exec_output() to apply line truncation first when both limits exceeded
- Account for 3-line marker overhead when calculating head/tail line budgets to ensure output never exceeds 256 lines
- Removed unused MODEL_FORMAT_HEAD_LINES and MODEL_FORMAT_TAIL_LINES constants
- Updated test expectations for new omitted line counts (147 vs 144 for 400 lines)
- Added regression test for scenario where 6000 tiny lines (12KB) previously violated line limit

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@0xRaduan
Copy link
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Contributor

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

0xRaduan and others added 3 commits November 12, 2025 11:14
- Fixed format_exec_output_reports_omitted_lines_and_keeps_head_and_tail to account for 3-line marker overhead
- Fixed format_exec_output_prefers_line_marker_when_both_limits_exceeded to use correct omitted count
- Updated assertions to match new behavior where available content lines = 256 - 3 = 253

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Updated head lines from 1-128 to 1-126 (126 lines)
- Updated tail lines from 273-400 to 274-400 (127 lines)
- Updated omitted count from 144 to 147 (400 - 253 = 147)
- Accounts for 3-line marker overhead in line truncation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@0xRaduan 0xRaduan force-pushed the claude/fix-byte-truncation-tail-011CUzauyoZNLSqRm4q2FQdd branch from c761219 to d014ece Compare November 12, 2025 10:28
@0xRaduan
Copy link
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Contributor

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@0xRaduan
Copy link
Contributor Author

@etraut-openai - fixed CI + the Codex comment, please feel free to assign for a review

Copy link
Contributor Author

@0xRaduan 0xRaduan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self-review

Comment on lines +217 to +218
#[cfg(test)]
mod tests {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it make sense to move to codex-rs/core/tests/suite/truncation.rs?

@etraut-openai etraut-openai removed the needs-response Additional information is requested label Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Byte truncation doesn't preserve command output tails, confusing codex (e.g. with cargo output)

2 participants