angular/components · error
Error: attempted to measure an item that isn't rendered.
Error message
Error: attempted to measure an item that isn't rendered.
What it means
CdkVirtualForOf.measureRangeSize(range, options) can only measure items that are currently rendered inside the viewport. The method throws when the requested index range falls outside the viewport's currently rendered range, since unrendered views have no DOM to measure.
Source
Thrown at src/cdk/scrolling/virtual-for-of.ts:215
this._onRenderedDataChange();
});
this._viewport.attach(this);
}
/**
* Measures the combined size (width for horizontal orientation, height for vertical) of all items
* in the specified range. Throws an error if the range includes items that are not currently
* rendered.
*/
measureRangeSize(range: ListRange, orientation: 'horizontal' | 'vertical'): number {
if (range.start >= range.end) {
return 0;
}
if (
(range.start < this._renderedRange.start || range.end > this._renderedRange.end) &&
(typeof ngDevMode === 'undefined' || ngDevMode)
) {
throw Error(`Error: attempted to measure an item that isn't rendered.`);
}
// The index into the list of rendered views for the first item in the range.
const renderedStartIndex = range.start - this._renderedRange.start;
// The length of the range we're measuring.
const rangeLen = range.end - range.start;
// Loop over all the views, find the first and land node and compute the size by subtracting
// the top of the first node from the bottom of the last one.
let firstNode: HTMLElement | undefined;
let lastNode: HTMLElement | undefined;
// Find the first node by starting from the beginning and going forwards.
for (let i = 0; i < rangeLen; i++) {
const view = this._viewContainerRef.get(i + renderedStartIndex) as EmbeddedViewRef<
CdkVirtualForOfContext<T>
> | null;
if (view && view.rootNodes.length) {View on GitHub (pinned to 0411926e7d)
Solutions
- Only call measureRangeSize for indexes within the currently rendered range (viewport.getRenderedRange())
- Clamp the requested range to the rendered range before measuring
- Use the uniform measureRangeSize option 'header/footer' semantics carefully: when measuring all items, ensure the whole list is rendered (e.g. temporarily render all or measure only visible items)
- Defer measurement until after rendering completes (afterNextRender / requestAnimationFrame) and re-check the rendered range
Example fix
// before
const range = { start: 0, end: this.data.length };
this.viewport.measureRangeSize(range);
// after
const rendered = this.viewport.getRenderedRange();
const range = {
start: Math.max(0, rendered.start),
end: Math.min(this.data.length, rendered.end),
};
if (range.end > range.start) {
this.viewport.measureRangeSize(range);
} Defensive patterns
Strategy: validation
Validate before calling
const rendered = viewport.getRenderedRange();
const clamped = {
start: Math.max(range.start, rendered.start),
end: Math.min(range.end, rendered.end),
};
if (clamped.end > clamped.start) {
viewport.measureRangeSize(clamped, options);
} Type guard
function isWithinRenderedRange(range: ListRange, viewport: CdkVirtualScrollViewport): boolean {
const rendered = viewport.getRenderedRange();
return range.start >= rendered.start && range.end <= rendered.end;
} Try / catch
try {
viewport.measureRangeSize(range, options);
} catch (e) {
if (e instanceof Error && e.message.includes("isn't rendered")) {
console.warn('Range not rendered; skipping measurement for', range);
} else {
throw e;
}
} Prevention
- Check viewport.getRenderedRange() before measuring
- Defer measurement until after rendering (requestAnimationFrame / afterNextRender)
- Never assume all list items are rendered in a virtual viewport
- Re-measure only when data and scroll position are stable
When it happens
Trigger: Calling measureRangeSize with a range whose start is before the rendered range start or whose end exceeds the rendered range end; measuring an index while scrolled far from it; measuring immediately after data changes before the rendered range updates.
Common situations: Programmatic autoscroll/measurement features that assume all items are rendered; measuring during fast scrolling when views outside the range were recycled; calling measureRangeSize before the viewport has rendered the requested indexes (e.g. right after pushing data).
Related errors
- cdk-virtual-scroll: scrolledIndexChange is currently not sup
- cdk-virtual-scroll: scrollToIndex is currently not supported
- CDK virtual scroll: maxBufferPx must be greater than or equa
- DOM portal content must be attached to a parent node.
- DOM portal content must be attached to a parent node.
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/87ca8118e4ddff44.
Report an issue: GitHub.