Skip to content

fix: truncate step summary to stay under GitHub's 1024k limit#1047

Open
sunnypatell wants to merge 2 commits intoanthropics:mainfrom
sunnypatell:fix/step-summary-size-limit
Open

fix: truncate step summary to stay under GitHub's 1024k limit#1047
sunnypatell wants to merge 2 commits intoanthropics:mainfrom
sunnypatell:fix/step-summary-size-limit

Conversation

@sunnypatell
Copy link

long Claude sessions (30+ min, many tool calls) generate step summary markdown that exceeds GitHub's hard 1024k limit for $GITHUB_STEP_SUMMARY, causing:

$GITHUB_STEP_SUMMARY upload aborted, supports content up to a size of 1024k, got 1026k.

the error is non-fatal (Claude's work still succeeds), but it's noisy and prevents viewing the execution summary. users currently have to set display_report: false to avoid it entirely, losing the summary for all sessions.

fixes #927

what changed

added truncateStepSummary() in format-turns.ts that:

  1. checks the markdown's byte size against a 1000k budget (leaves 24k headroom for content from earlier steps in the same job)
  2. if over budget, cuts at the last section boundary (---) to avoid breaking mid-content
  3. appends a truncation notice explaining the limit and pointing to display_report: false
  4. handles multi-byte characters correctly via TextEncoder/TextDecoder (no mid-codepoint cuts)

applied in both the formatted report path and the raw JSON fallback path in writeStepSummary().

tests

5 new tests in format-turns.test.ts:

  • under-limit content passes through unchanged
  • over-limit content is truncated with notice
  • cuts at last section separator when one exists in the latter half
  • multi-byte characters (emoji) survive without corruption
  • default limit matches GitHub's constraint

all 35 tests pass.

- added truncateStepSummary() that checks byte size against GitHub's
  hard limit and cuts at the last section boundary (---) when possible
- uses 1000k budget (not 1024k) to leave headroom for content from
  earlier steps in the same job
- appends a truncation notice pointing users to display_report: false
- handles multi-byte characters correctly via TextEncoder/TextDecoder
- applied to both the formatted report and the raw JSON fallback path
- added 5 tests covering: under-limit passthrough, over-limit truncation,
  section boundary cutting, multi-byte character safety, default limit

fixes anthropics#927
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds step-summary truncation to prevent GitHub Actions $GITHUB_STEP_SUMMARY size-limit issues when rendering large Claude Code reports.

Changes:

  • Introduces truncateStepSummary() to truncate markdown output to a byte budget and append a notice.
  • Applies truncation when writing both formatted and fallback (raw JSON) step summaries.
  • Adds unit tests covering truncation behavior, section-boundary cutting, and multi-byte character handling.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/entrypoints/format-turns.ts Adds truncateStepSummary() and a default byte budget for step-summary output.
src/entrypoints/run.ts Wraps step-summary writes with truncateStepSummary() to avoid oversize reports.
test/format-turns.test.ts Adds tests validating truncation and UTF-8/multi-byte behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

- guarded against budget going negative when maxBytes < notice size
- added re-verification loop for multi-byte boundary edge cases where
  TextDecoder replacement chars could inflate encoded size
- tightened section boundary test to assert Section 3 is excluded
- renamed default limit test to reflect 1000k headroom, not 1024k
- added edge case test for maxBytes smaller than notice
@sunnypatell
Copy link
Author

addressing copilot's 5 inline comments (3 fixed in d5b55ae, 2 intentionally kept as-is):

fixed in d5b55ae:

  1. budget going negative (format-turns.ts:443) - added a guard: if maxBytes <= noticeBytes, returns just the notice trimmed to fit. handles the edge case where the limit is absurdly small.

  2. replacement char inflating encoded size (format-turns.ts:453) - added a re-verification loop that trims one character at a time if the re-encoded result exceeds the budget after TextDecoder replaces incomplete multi-byte sequences with U+FFFD.

  3. test name mismatch (format-turns.test.ts:469) - renamed to "uses default limit with headroom below GitHub's 1024k constraint" to reflect the intentional 1000k budget.

  4. tighter section boundary assertions (format-turns.test.ts:450) - added not.toContain("Section 3") and not.toContain("C".repeat(50)) to validate Section 3 content was excluded. also fixed the limit calculation so it actually triggers the boundary cut.

intentionally not changed:

  1. checking existing summary file size (run.ts:108) - the 24k headroom (1000k vs 1024k) covers realistic earlier-step content. stat-ing the summary file on every write adds I/O and complexity for a scenario that effectively doesn't happen in practice (earlier steps would need to write 24k+ of summary, which is extremely unusual for steps that precede Claude). if this ever becomes a real problem, the fix would be to reduce the budget further, not to add file I/O.

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.

GITHUB_STEP_SUMMARY exceeds 1024k limit on long sessions

2 participants