{"record":{"id":"25822a8cb2a5c72a","repo":"mrdoob/three.js","slug":"three-batchedmesh-all-attributes-must-have-a-cons","errorCode":null,"errorMessage":"THREE.BatchedMesh: All attributes must have a consistent itemSize and normalized value.","messagePattern":"THREE\\.BatchedMesh: All attributes must have a consistent itemSize and normalized value\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/objects/BatchedMesh.js","lineNumber":440,"sourceCode":"\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 *\n\t * @param {number} instanceId - The instance to validate.\n\t */\n\tvalidateInstanceId( instanceId ) {\n\n\t\tconst instanceInfo = this._instanceInfo;\n\t\tif ( instanceId < 0 || instanceId >= instanceInfo.length || instanceInfo[ instanceId ].active === false ) {\n\n\t\t\tthrow new Error( `THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instance is either out of range or has been deleted.` );","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/objects/BatchedMesh.js#L422-L458","documentation":"Thrown by BatchedMesh._validateGeometry() when a shared attribute has a mismatched `itemSize` or `normalized` flag between the added geometry and the batch's combined geometry. Even if the attribute exists, its component count and normalization must match exactly.","triggerScenarios":"Adding a geometry whose 'uv' is itemSize 2 but the batch's is itemSize 4; mixing normalized (e.g. normalized color attributes) with non-normalized ones; a custom attribute with a different component count than the batch's first geometry.","commonSituations":"Batching geometries with different vertex layouts; color attributes where some are normalized byte arrays and others are float; uv1 vs uv0 confusion; loaded glTF geometries with different attribute encodings.","solutions":["Normalize every shared attribute to the same itemSize and normalized value before adding.","Re-create the mismatched attribute with the correct component count and normalized flag.","Separate geometries with incompatible attribute layouts into different BatchedMesh instances."],"exampleFix":"// before\n// batch 'color' is itemSize 3, float\nbatch.addGeometry( geomWithByteColor ); // itemSize 4, normalized\n\n// after\ngeomWithByteColor.setAttribute( 'color', new Float32BufferAttribute( geomWithByteColor.attributes.color.array.filter((_,i)=>i%4<3), 3 ) );\nbatch.addGeometry( geomWithByteColor );","handlingStrategy":"validation","validationCode":"function assertAttributeLayoutMatches( batch, geometry ) {\n  for ( const name in batch.geometry.attributes ) {\n    const a = geometry.getAttribute( name ), b = batch.geometry.getAttribute( name );\n    if ( a.itemSize !== b.itemSize || a.normalized !== b.normalized ) {\n      throw new Error( `Attribute '${ name }' layout mismatch (itemSize/normalized).` );\n    }\n  }\n}","typeGuard":"const attributeLayoutsMatch = ( batch, geometry ) => Object.keys( batch.geometry.attributes ).every( ( n ) => {\n  const a = geometry.getAttribute( n ), b = batch.geometry.getAttribute( n );\n  return a.itemSize === b.itemSize && a.normalized === b.normalized;\n} );","tryCatchPattern":null,"preventionTips":["Use a consistent itemSize and normalized flag for each shared attribute.","Re-encode mismatched attributes (e.g. normalized bytes -> floats) before adding.","Separate geometries with incompatible layouts into different batches."],"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"}