{"record":{"id":"80ae746f1cc4dc7d","repo":"mrdoob/three.js","slug":"three-webglattributes-the-size-of-the-buffer-attr","errorCode":null,"errorMessage":"THREE.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size. Resizing buffer attributes is not supported.","messagePattern":"THREE\\.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size\\. Resizing buffer attributes is not supported\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderers/webgl/WebGLAttributes.js","lineNumber":214,"sourceCode":"\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tconst data = buffers.get( attribute );\n\n\t\tif ( data === undefined ) {\n\n\t\t\tbuffers.set( attribute, createBuffer( attribute, bufferType ) );\n\n\t\t} else if ( data.version < attribute.version ) {\n\n\t\t\tif ( data.size !== attribute.array.byteLength ) {\n\n\t\t\t\tthrow 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.' );\n\n\t\t\t}\n\n\t\t\tupdateBuffer( data.buffer, attribute, bufferType );\n\n\t\t\tdata.version = attribute.version;\n\n\t\t}\n\n\t}\n\n\treturn {\n\n\t\tget: get,\n\t\tremove: remove,\n\t\tupdate: update\n\n\t};","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/renderers/webgl/WebGLAttributes.js#L196-L232","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before - reassign a larger array on the same attribute\nattr.array = new Float32Array(newData); // larger byteLength\nattr.version++; // triggers update() -> throws\n\n// after - replace the attribute\ngeom.setAttribute('position', new BufferAttribute(new Float32Array(newData), 3));","handlingStrategy":"validation","validationCode":"function setOrUpdateAttribute(geometry, name, array, itemSize) {\n  const existing = geometry.getAttribute(name);\n  if (!existing || existing.array.byteLength !== array.byteLength) {\n    geometry.setAttribute(name, new THREE.BufferAttribute(array, itemSize));\n  } else {\n    existing.array.set(array);\n    existing.needsUpdate = true;\n  }\n}","typeGuard":"function canUpdateInPlace(attribute, newArray) {\n  return attribute && attribute.array.byteLength === newArray.byteLength;\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["webgl","buffer-attribute","geometry","resource-lifecycle","dynamic-data"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}