mrdoob/three.js · error · Error
THREE.BatchedMesh: Invalid geometryId ${geometryId}. Geometr
Error message
THREE.BatchedMesh: Invalid geometryId ${geometryId}. Geometry is either out of range or has been deleted. What it means
Thrown by BatchedMesh.validateGeometryId() when the geometryId is negative, greater than or equal to the geometry info list length, or refers to a deleted (inactive) geometry. APIs like addInstance(geometryId) validate the geometry id first.
Source
Thrown at src/objects/BatchedMesh.js:474
if ( instanceId < 0 || instanceId >= instanceInfo.length || instanceInfo[ instanceId ].active === false ) {
throw new Error( `THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instance is either out of range or has been deleted.` );
}
}
/**
* Validates the geometry defined by the given ID.
*
* @param {number} geometryId - The geometry to validate.
*/
validateGeometryId( geometryId ) {
const geometryInfoList = this._geometryInfo;
if ( geometryId < 0 || geometryId >= geometryInfoList.length || geometryInfoList[ geometryId ].active === false ) {
throw new Error( `THREE.BatchedMesh: Invalid geometryId ${geometryId}. Geometry is either out of range or has been deleted.` );
}
}
/**
* Takes a sort a function that is run before render. The function takes a list of instances to
* sort and a camera. The objects in the list include a "z" field to perform a depth-ordered sort with.
*
* @param {Function} func - The custom sort function.
* @return {BatchedMesh} A reference to this batched mesh.
*/
setCustomSort( func ) {
this.customSort = func;
return this;
}View on GitHub (pinned to da05705fa3)
Solutions
- Use only the id returned by addGeometry(); do not assume ids are contiguous after deletions.
- Invalidate cached geometry ids when the corresponding geometry is deleted.
- Bound-check the id against the geometry count and track active ids in your own map.
Example fix
// before batch.deleteGeometry( geometryId ); batch.addInstance( geometryId ); // geometryId now invalid // after batch.deleteGeometry( geometryId ); // remove geometryId from your lookup; re-add geometry if still needed
Defensive patterns
Strategy: validation
Validate before calling
function isValidGeometryId( batch, id ) {
const list = batch._geometryInfo;
return id >= 0 && id < list.length && list[ id ].active === true;
}
if ( ! isValidGeometryId( batch, id ) ) throw new RangeError( `Invalid geometryId ${ id }` ); Type guard
const isActiveGeometry = ( batch, id ) => isValidGeometryId( batch, id );
Try / catch
try {
batch.addInstance( geometryId );
} catch ( e ) {
if ( /Invalid geometryId/.test( e.message ) ) {
// geometry was deleted; re-add or skip
} else throw e;
} Prevention
- Use only ids returned by addGeometry().
- Do not assume geometry ids stay contiguous after deletions.
- Clear cached geometry ids when the geometry is deleted.
When it happens
Trigger: Using a geometryId returned before deleteGeometry() was called; passing a geometry index that was never added; referencing a geometry id across a repack/optimize that invalidated it; off-by-one indexing.
Common situations: Caching geometry ids across geometry deletion/re-addition; assuming ids are contiguous after deletion; passing the index into a user array instead of the BatchedMesh-returned geometryId.
Related errors
- THREE.BatchedMesh: All geometries must consistently have "in
- THREE.BatchedMesh: Added geometry missing "${ attributeName
- THREE.BatchedMesh: All attributes must have a consistent ite
- THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instanc
- invalid length
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/1586ee8f6b71ed63.
Report an issue: GitHub.