mrdoob/three.js · error · Error
THREE.WebGLAttributes: The size of the buffer attribute's ar
Error message
THREE.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size. Resizing buffer attributes is not supported.
What it means
Thrown by WebGLAttributes.update() when a BufferAttribute's version was bumped (marking it dirty) but its underlying array buffer's byteLength changed since the GPU buffer was first created. WebGL buffers are allocated at a fixed size; the renderer does not silently reallocate, so a size change after creation is rejected as a programming error.
Source
Thrown at src/renderers/webgl/WebGLAttributes.js:214
} );
}
return;
}
const data = buffers.get( attribute );
if ( data === undefined ) {
buffers.set( attribute, createBuffer( attribute, bufferType ) );
} else if ( data.version < attribute.version ) {
if ( data.size !== attribute.array.byteLength ) {
throw new Error( 'THREE.WebGLAttributes: The size of the buffer attribute\'s array buffer does not match the original size. Resizing buffer attributes is not supported.' );
}
updateBuffer( data.buffer, attribute, bufferType );
data.version = attribute.version;
}
}
return {
get: get,
remove: remove,
update: update
};View on GitHub (pinned to da05705fa3)
Solutions
- Replace the attribute entirely when the size changes: `geometry.setAttribute('position', new BufferAttribute(newArray, 3))`.
- Pre-allocate a maximum-size buffer and update a subset (use updateRanges) rather than resizing.
- Dispose the geometry/attribute and rebuild it when the data size changes.
- If shrinking temporarily, keep the original buffer length and only mark the used range dirty.
Example fix
// before - reassign a larger array on the same attribute
attr.array = new Float32Array(newData); // larger byteLength
attr.version++; // triggers update() -> throws
// after - replace the attribute
geom.setAttribute('position', new BufferAttribute(new Float32Array(newData), 3)); Defensive patterns
Strategy: validation
Validate before calling
function setOrUpdateAttribute(geometry, name, array, itemSize) {
const existing = geometry.getAttribute(name);
if (!existing || existing.array.byteLength !== array.byteLength) {
geometry.setAttribute(name, new THREE.BufferAttribute(array, itemSize));
} else {
existing.array.set(array);
existing.needsUpdate = true;
}
} Type guard
function canUpdateInPlace(attribute, newArray) {
return attribute && attribute.array.byteLength === newArray.byteLength;
} Prevention
- Never resize `attribute.array` in place; replace the attribute when the size changes.
- Pre-allocate a maximum-size buffer for dynamic systems and update a sub-range.
- Dispose and rebuild geometry when the data shape changes fundamentally.
When it happens
Trigger: Mutating `attribute.array` to a differently-sized typed array (e.g. pushing/popping and reassigning a new Float32Array) then bumping `attribute.version`, rather than replacing the BufferAttribute on the geometry.
Common situations: Dynamic line/particle systems that grow or shrink over time. Reassigning `attribute.array = new Float32Array(newLength)` and `attribute.needsUpdate = true` instead of replacing the attribute. Geometry pooling where the same attribute object is repurposed for different sizes.
Related errors
- THREE.WebGLBackend: Unsupported buffer data format:
- THREE.WebGLAttributes: Unsupported buffer data format:
- THREE.WebGPURenderer: ReadbackBuffer must be released before
- THREE.WebGPUAttributeUtils: Bad vertex format item size.
- THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinat
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/80ae746f1cc4dc7d.
Report an issue: GitHub.