Skip to content

fix: clamp gutter indicator dimensions to prevent negative Rect (fixes #313727)#313794

Draft
vs-code-engineering[bot] wants to merge 1 commit intomainfrom
fix/gutter-indicator-negative-rect-313727-91c18f1cf4ff163d
Draft

fix: clamp gutter indicator dimensions to prevent negative Rect (fixes #313727)#313794
vs-code-engineering[bot] wants to merge 1 commit intomainfrom
fix/gutter-indicator-negative-rect-313727-91c18f1cf4ff163d

Conversation

@vs-code-engineering
Copy link
Copy Markdown
Contributor

Summary

The Rect constructor in rect.ts throws BugIndicatingError("Invalid arguments: Vertically offset by 4") when gutterIndicatorView.ts computes a negative height for the gutter viewport. When layout.height is very small (< 4px, e.g. during editor resize or collapse), gutterHeightWithoutPadding = layout.height - 2 * gutterViewPortPaddingTop becomes negative, and Rect.fromLeftTopWidthHeight(left, top, width, negativeHeight) produces top > bottom, triggering the validation error. This affects all platforms (Linux, Mac, Windows).

Fixes #313727
Recommended reviewer: @hediet

Culprit Commit

Not identified — pre-existing pattern. This is the same class of bug previously fixed in #301197 (horizontal axis). The vertical axis was not guarded. The error resurfaced because the same computation path lacks clamping for both dimensions.

Code Flow

sequenceDiagram
    participant Layout as "EditorLayoutInfo"
    participant Gutter as "GutterIndicatorView._computeFn"
    participant RectFactory as "Rect.fromLeftTopWidthHeight"
    participant RectCtor as "Rect constructor"

    Layout->>Gutter: layout.height is small value
    Note over Gutter: gutterHeightWithoutPadding = 0 - 4 = -4
    Gutter->>RectFactory: fromLeftTopWidthHeight with negative height
    RectFactory->>RectCtor: new Rect with top greater than bottom
    Note over RectCtor: throws BugIndicatingError
Loading

Affected Files

File Role
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts Root cause — produces negative dimensions
src/vs/editor/common/core/2d/rect.ts Crash site — validates constructor args

Repro Steps

  1. Open VS Code with inline completions enabled
  2. Resize the editor to a very small height (< 4px visible area), or trigger a layout where the editor height is minimal (e.g., during panel maximize transitions)
  3. Have an active inline completion suggestion with gutter indicator visible
  4. The error fires when the derived observable recomputes the gutter layout

How the Fix Works

Chosen approach (gutterIndicatorView.ts:348-349): Clamp both gutterWidthWithoutPadding and gutterHeightWithoutPadding to Math.max(0, ...) at the data-producer site. This follows the data-producer principle — fix where invalid data is created, not at the crash site (Rect constructor). When the editor is too small to display the gutter, a zero-size rect is semantically correct (nothing to render).

Alternatives considered: Adding a guard in the Rect constructor to clamp instead of throw — rejected because the constructor's validation catches real bugs elsewhere; silencing it would hide future errors across all callers.

Recommended Owner

@hediet — owner of inline completions and gutter indicator code, reviewer on prior fix #301197

Generated by errors-fix · ● 5.8M ·

When layout.height is very small (< 4px), gutterHeightWithoutPadding
becomes negative, causing Rect.fromLeftTopWidthHeight to throw
'Invalid arguments: Vertically offset by N'. Same for width.

Clamp both dimensions to Math.max(0, ...) at the computation site.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

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

Fixes a crash in the inline edits gutter indicator layout computation by preventing invalid Rect construction when the editor is resized/collapsed to very small dimensions.

Changes:

  • Clamp computed gutter viewport width/height to be non-negative before creating a Rect.
Show a summary per file
File Description
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts Clamp gutter viewport dimensions to avoid negative sizes that can trigger Rect validation errors.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment on lines 351 to 352
const gutterViewPortWithoutStickyScrollWithoutPaddingTop = gutterViewPortWithStickyScroll.withTop(this._stickyScrollHeight.read(reader));
const gutterViewPortWithoutStickyScroll = gutterViewPortWithStickyScroll.withTop(gutterViewPortWithoutStickyScrollWithoutPaddingTop.top + gutterViewPortPaddingTop);
@microsoft microsoft deleted a comment from vs-code-engineering Bot May 2, 2026
@vs-code-engineering
Copy link
Copy Markdown
Contributor Author

Follow-up: Review Comment Analysis

Trigger: cron_review_comments

Review Comment from Copilot PR Reviewer

@copilot-pull-request-reviewer flagged that clamping gutterHeightWithoutPadding alone is insufficient — withTop(stickyScrollHeight) on line 351 can still produce an invalid Rect when stickyScrollHeight > gutterViewPortWithStickyScroll.bottom (possible when the editor height is very small but the sticky scroll widget retains a non-zero height).

Suggested Fix

Clamp the sticky-scroll top (and the subsequent + gutterViewPortPaddingTop top) to gutterViewPortWithStickyScroll.bottom:

 const gutterViewPortWithStickyScroll = Rect.fromLeftTopWidthHeight(gutterViewPortPaddingLeft, gutterViewPortPaddingTop, gutterWidthWithoutPadding, gutterHeightWithoutPadding);
-const gutterViewPortWithoutStickyScrollWithoutPaddingTop = gutterViewPortWithStickyScroll.withTop(this._stickyScrollHeight.read(reader));
-const gutterViewPortWithoutStickyScroll = gutterViewPortWithStickyScroll.withTop(gutterViewPortWithoutStickyScrollWithoutPaddingTop.top + gutterViewPortPaddingTop);
+const stickyScrollTop = Math.min(this._stickyScrollHeight.read(reader), gutterViewPortWithStickyScroll.bottom);
+const gutterViewPortWithoutStickyScrollWithoutPaddingTop = gutterViewPortWithStickyScroll.withTop(stickyScrollTop);
+const gutterViewPortWithoutStickyScroll = gutterViewPortWithStickyScroll.withTop(Math.min(gutterViewPortWithoutStickyScrollWithoutPaddingTop.top + gutterViewPortPaddingTop, gutterViewPortWithStickyScroll.bottom));

This ensures both withTop calls never exceed bottom, producing an empty rect (height 0) instead of an invalid one when the editor is too small.

Status

  • ✅ CI: All 30 checks passing
  • ⚠️ Could not push the fix automatically (cross-repo push limitation). The above diff should be applied manually to gutterIndicatorView.ts at lines 350-352.

Generated by errors-fix-driver · ● 4.2M ·

@vs-code-engineering vs-code-engineering Bot requested review from Copilot and removed request for Copilot May 5, 2026 00:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Regression] Invalid arguments: Vertically offset by 4 [Unhandled Error] Invalid arguments: Horizontally/Vertically offset by 4

2 participants