Skip to content

fix(web): keep oversized diff lines from locking the UI#2338

Open
notkadez wants to merge 2 commits intopingdotgg:mainfrom
notkadez:kayden/skip-oversized-diff-lines
Open

fix(web): keep oversized diff lines from locking the UI#2338
notkadez wants to merge 2 commits intopingdotgg:mainfrom
notkadez:kayden/skip-oversized-diff-lines

Conversation

@notkadez
Copy link
Copy Markdown

@notkadez notkadez commented Apr 24, 2026

What Changed

Adds a render-safety guard to the web diff panel so files with pathologically long diff lines are skipped instead of being passed into the browser diff renderer.

This includes:

  • a shared canRenderFileDiff helper in diffRendering
  • a MAX_RENDERABLE_DIFF_LINE_LENGTH limit for oversized added/deleted lines
  • updated DiffPanel sorting and rendering behavior
  • user-facing fallback copy for files that are too large to render safely
  • unit coverage for both accepted and rejected line lengths

Renderable diffs continue to display normally. Files that exceed the line-length threshold still appear in the diff list, but their diff body is collapsed and replaced with guidance to open the file directly.

Why

A single extremely long added or deleted line can make browser-side diff rendering expensive enough to freeze or severely degrade the UI, even when the rest of the patch is small.

This keeps the diff panel reliable under pathological inputs without rejecting or hiding the entire patch. Safe files remain visible, oversized files remain represented, and users can still inspect the full change in their editor when needed.

The implementation is intentionally localized: shared diff-rendering logic owns the renderability decision, and DiffPanel uses that result only to avoid the unsafe render path.

UI Changes

For files that are too large to render safely, the diff panel now shows:

  • the file header in a collapsed state
  • fallback text: This file is too large to display. Open the file to inspect the change.

There are no layout or interaction changes for normal-sized diffs.

Screenshot 2026-04-24 at 2 09 00 PM

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Low Risk
Localized UI rendering guardrails with minimal behavioral change for normal diffs; primary risk is edge-case misclassification causing a file diff to be unnecessarily collapsed.

Overview
Prevents the diff UI from freezing on pathological inputs by introducing canRenderFileDiff and a MAX_RENDERABLE_DIFF_LINE_LENGTH threshold in diffRendering.

DiffPanel now tags each file diff as renderable/unrenderable, sorts unrenderable files to the bottom, renders them in a collapsed state, and shows a short fallback message instructing users to open the file in an editor. Unit tests were added to cover the line-length acceptance/rejection behavior.

Reviewed by Cursor Bugbot for commit e2a1242. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Collapse oversized diff lines in DiffPanel to prevent UI lockup

  • Adds canRenderFileDiff in diffRendering.ts that checks if any line in a file diff exceeds MAX_RENDERABLE_DIFF_LINE_LENGTH (500,000 chars).
  • Files that fail this check are rendered collapsed with a 'too large to display' message in DiffPanel.tsx.
  • Unrenderable files are sorted to the bottom of the diff list, after renderable files.
  • Behavioral Change: files with very long lines are now always collapsed by default rather than rendered fully.

Macroscope summarized e2a1242.


Open in Devin Review

- Introduced `canRenderFileDiff` function to determine if a file diff can be displayed based on line length limits.
- Updated `DiffPanel` to utilize this function, providing user feedback for large files.
- Added tests for the new rendering logic to ensure proper functionality.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ca733b87-af39-4126-ba98-1b01c8db10a6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 24, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 24, 2026

Approvability

Verdict: Approved

Straightforward defensive fix that prevents UI lockup from oversized diff lines by collapsing files with lines exceeding 500k characters. Self-contained change with unit tests, no business logic impact.

You can customize Macroscope's approvability policy. Learn more.

Comment on lines +315 to +318
const renderOrder = Number(!left.canRender) - Number(!right.canRender);
if (renderOrder !== 0) {
return renderOrder;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure about this, but everything else looks good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants