angular/components · error

CDK virtual scroll: maxBufferPx must be greater than or equa

Error message

CDK virtual scroll: maxBufferPx must be greater than or equal to minBufferPx

What it means

The CDK virtual scrolling viewport keeps extra rendered content around the visible area. minBufferPx is how much buffer must be exhausted before more is rendered, and maxBufferPx is how much is rendered at that point; if max is smaller than min, the buffering logic cannot function, so the FixedSizeVirtualScrollStrategy rejects the configuration at update time.

Source

Thrown at src/cdk/scrolling/fixed-size-virtual-scroll.ts:70

    this._updateTotalContentSize();
    this._updateRenderedRange();
  }

  /** Detaches this scroll strategy from the currently attached viewport. */
  detach() {
    this._scrolledIndexChange.complete();
    this._viewport = null;
  }

  /**
   * Update the item size and buffer size.
   * @param itemSize The size of the items in the virtually scrolling list.
   * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more
   * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.
   */
  updateItemAndBufferSize(itemSize: number, minBufferPx: number, maxBufferPx: number) {
    if (maxBufferPx < minBufferPx && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error('CDK virtual scroll: maxBufferPx must be greater than or equal to minBufferPx');
    }
    this._itemSize = itemSize;
    this._minBufferPx = minBufferPx;
    this._maxBufferPx = maxBufferPx;
    this._updateTotalContentSize();
    this._updateRenderedRange();
  }

  /** @docs-private Implemented as part of VirtualScrollStrategy. */
  onContentScrolled() {
    this._updateRenderedRange();
  }

  /** @docs-private Implemented as part of VirtualScrollStrategy. */
  onDataLengthChanged() {
    this._updateTotalContentSize();
    this._updateRenderedRange();
  }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Ensure maxBufferPx >= minBufferPx in the template bindings or strategy configuration
  2. If values are dynamic, clamp before applying: maxBufferPx = Math.max(minBufferPx, computedMax)
  3. Swap the values if they were accidentally reversed
  4. Remove explicit buffer bindings to use defaults (minBufferPx=100px, maxBufferPx=200px) if custom buffering is not required

Example fix

<!-- before -->
<cdk-virtual-scroll-viewport [itemSize]="50" [minBufferPx]="500" [maxBufferPx]="200">
<!-- after -->
<cdk-virtual-scroll-viewport [itemSize]="50" [minBufferPx]="200" [maxBufferPx]="500">
Defensive patterns

Strategy: validation

Validate before calling

if (maxBufferPx < minBufferPx) {
  throw new Error('maxBufferPx must be >= minBufferPx (got ' + minBufferPx + '/' + maxBufferPx + ')');
}
strategy.updateItemAndBufferSize(itemSize, minBufferPx, maxBufferPx);

Type guard

function hasValidBuffers(config: { minBufferPx: number; maxBufferPx: number }): boolean {
  return config.maxBufferPx >= config.minBufferPx && config.minBufferPx >= 0;
}

Try / catch

try {
  viewport.scrollStrategy.updateItemAndBufferSize(itemSize, min, max);
} catch (e) {
  if (e instanceof Error && e.message.includes('maxBufferPx')) {
    viewport.scrollStrategy.updateItemAndBufferSize(itemSize, Math.min(min, max), Math.max(min, max));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling updateItemAndBufferSize(itemSize, minBufferPx, maxBufferPx) with maxBufferPx < minBufferPx; binding [maxBufferPx] to a value smaller than [minBufferPx] on cdk-virtual-scroll-viewport; dynamically shrinking maxBufferPx below minBufferPx at runtime.

Common situations: Copy-pasted buffer values with the names swapped; computing buffer sizes from viewport dimensions where max ends up smaller on small screens; setting minBufferPx=500 but maxBufferPx=200.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/d63037afc459ee8a. Report an issue: GitHub.