mrdoob/three.js · error · Error
THREE.BatchedMesh: All geometries must consistently have "in
Error message
THREE.BatchedMesh: All geometries must consistently have "index".
What it means
Thrown by BatchedMesh._validateGeometry() when the added geometry's indexed/non-indexed status differs from the batch's combined geometry. The check is `Boolean(geometry.getIndex()) !== Boolean(batchGeometry.getIndex())` — all geometries in a batch must consistently use an index buffer or consistently omit one.
Source
Thrown at src/objects/BatchedMesh.js:424
geometry.setIndex( new BufferAttribute( indexArray, 1 ) );
}
this._geometryInitialized = true;
}
}
// Make sure the geometry is compatible with the existing combined geometry attributes
_validateGeometry( geometry ) {
// check to ensure the geometries are using consistent attributes and indices
const batchGeometry = this.geometry;
if ( Boolean( geometry.getIndex() ) !== Boolean( batchGeometry.getIndex() ) ) {
throw new Error( 'THREE.BatchedMesh: All geometries must consistently have "index".' );
}
for ( const attributeName in batchGeometry.attributes ) {
if ( ! geometry.hasAttribute( attributeName ) ) {
throw new Error( `THREE.BatchedMesh: Added geometry missing "${ attributeName }". All geometries must have consistent attributes.` );
}
const srcAttribute = geometry.getAttribute( attributeName );
const dstAttribute = batchGeometry.getAttribute( attributeName );
if ( srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized ) {
throw new Error( 'THREE.BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );
}View on GitHub (pinned to da05705fa3)
Solutions
- Make all geometries consistent: call `.toNonIndexed()` on every indexed geometry, or call `.setIndex()` to index every non-indexed one.
- Decide the batch's convention with the first addGeometry call, then ensure every subsequent geometry matches.
- Group indexed and non-indexed geometries into separate BatchedMesh instances.
Example fix
// before batch.addGeometry( indexedBox ); batch.addGeometry( nonIndexedGeom ); // after batch.addGeometry( indexedBox ); batch.addGeometry( nonIndexedGeom.toNonIndexed ? nonIndexedGeom : nonIndexedGeom ); // or normalize all to indexed/non-indexed before adding
Defensive patterns
Strategy: validation
Validate before calling
function assertCompatibleIndexing( batch, geometry ) {
if ( Boolean( geometry.getIndex() ) !== Boolean( batch.geometry.getIndex() ) ) {
throw new Error( 'Geometry indexing does not match the batch.' );
}
} Type guard
const matchesBatchIndexing = ( batch, geometry ) => Boolean( geometry.getIndex() ) === Boolean( batch.geometry.getIndex() );
Prevention
- Normalize all geometries to indexed or all to non-indexed before batching.
- Establish the batch convention with the first addGeometry call.
- Use separate BatchedMesh instances for indexed vs non-indexed sets.
When it happens
Trigger: Mixing indexed geometries (e.g. BoxGeometry, PlaneGeometry) with non-indexed ones (e.g. some custom BufferGeometries) in the same BatchedMesh; adding a geometry after calling addGeometry with a differently-indexed first geometry.
Common situations: Batching a heterogeneous set of geometries; loading geometries from different loaders where some are indexed and some are not; converting a geometry to non-indexed (`geometry.toNonIndexed()`) for some but not all batch members.
Related errors
- THREE.BatchedMesh: Added geometry missing "${ attributeName
- THREE.BatchedMesh: All attributes must have a consistent ite
- THREE.BatchedMesh: Invalid geometryId ${geometryId}. Geometr
- THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instanc
- invalid length
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/8bc41fa2b38a4344.
Report an issue: GitHub.