{"record":{"id":"df5ac455b790b434","repo":"mrdoob/three.js","slug":"three-batchedmesh-added-geometry-missing-attr","errorCode":null,"errorMessage":"THREE.BatchedMesh: Added geometry missing \"${ attributeName }\". All geometries must have consistent attributes.","messagePattern":"THREE\\.BatchedMesh: Added geometry missing \"(.+?)\"\\. All geometries must have consistent attributes\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/objects/BatchedMesh.js","lineNumber":432,"sourceCode":"\n\t}\n\n\t// Make sure the geometry is compatible with the existing combined geometry attributes\n\t_validateGeometry( geometry ) {\n\n\t\t// check to ensure the geometries are using consistent attributes and indices\n\t\tconst batchGeometry = this.geometry;\n\t\tif ( Boolean( geometry.getIndex() ) !== Boolean( batchGeometry.getIndex() ) ) {\n\n\t\t\tthrow new Error( 'THREE.BatchedMesh: All geometries must consistently have \"index\".' );\n\n\t\t}\n\n\t\tfor ( const attributeName in batchGeometry.attributes ) {\n\n\t\t\tif ( ! geometry.hasAttribute( attributeName ) ) {\n\n\t\t\t\tthrow new Error( `THREE.BatchedMesh: Added geometry missing \"${ attributeName }\". All geometries must have consistent attributes.` );\n\n\t\t\t}\n\n\t\t\tconst srcAttribute = geometry.getAttribute( attributeName );\n\t\t\tconst dstAttribute = batchGeometry.getAttribute( attributeName );\n\t\t\tif ( srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized ) {\n\n\t\t\t\tthrow new Error( 'THREE.BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Validates the instance defined by the given ID.\n\t *","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/objects/BatchedMesh.js#L414-L450","documentation":"Thrown by BatchedMesh._validateGeometry() when an added geometry is missing an attribute that the batch's combined geometry already has. The loop iterates the batch's existing attributes and requires every new geometry to provide each one, so all geometries must share the same attribute set.","triggerScenarios":"Adding a geometry that lacks 'uv' or 'normal' or 'color' to a batch whose first geometry had those attributes; mixing geometries with different attribute sets (e.g. a BoxGeometry with uv into a batch started with a geometry that also had color).","commonSituations":"Batching geometries from different sources (procedural vs. loaded) with inconsistent attributes; adding a geometry that was stripped of some attributes for optimization; forgetting to add a color/uv attribute to a custom geometry.","solutions":["Ensure every geometry has the same set of attributes as the first geometry added to the batch.","Add missing attributes (e.g. generate uvs/normals) before adding the geometry.","Remove extra attributes from the batch's first geometry if you do not need them across all members."],"exampleFix":"// before\nbatch.addGeometry( geomWithColor );\nbatch.addGeometry( geomWithoutColor ); // missing 'color'\n\n// after\ngeomWithoutColor.setAttribute( 'color', new Float32BufferAttribute( new Float32Array( count * 3 ), 3 ) );\nbatch.addGeometry( geomWithoutColor );","handlingStrategy":"validation","validationCode":"function assertHasBatchAttributes( batch, geometry ) {\n  for ( const name in batch.geometry.attributes ) {\n    if ( ! geometry.hasAttribute( name ) ) {\n      throw new Error( `Geometry missing attribute '${ name }' required by the batch.` );\n    }\n  }\n}","typeGuard":"const hasAllBatchAttributes = ( batch, geometry ) => Object.keys( batch.geometry.attributes ).every( ( n ) => geometry.hasAttribute( n ) );","tryCatchPattern":null,"preventionTips":["Ensure every geometry shares the batch's full attribute set.","Generate missing uvs/normals/colors before adding.","Trim unneeded attributes from the first geometry if not all members have them."],"tags":["batched-mesh","geometry","attributes","validation"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}