mrdoob/three.js · error · Error
THREE.BatchedMesh: Maximum item count reached.
Error message
THREE.BatchedMesh: Maximum item count reached.
What it means
Thrown by BatchedMesh.addInstance() when `_instanceInfo.length >= maxInstanceCount` AND there are no freed ids available in `_availableInstanceIds`. The batch is statically sized by the maxInstanceCount constructor argument; once full (and with no deletions to recycle ids), no further instances can be added.
Source
Thrown at src/objects/BatchedMesh.js:568
}
}
/**
* Adds a new instance to the batch using the geometry of the given ID and returns
* a new id referring to the new instance to be used by other functions.
*
* @param {number} geometryId - The ID of a previously added geometry via {@link BatchedMesh#addGeometry}.
* @return {number} The instance ID.
*/
addInstance( geometryId ) {
const atCapacity = this._instanceInfo.length >= this.maxInstanceCount;
// ensure we're not over geometry
if ( atCapacity && this._availableInstanceIds.length === 0 ) {
throw new Error( 'THREE.BatchedMesh: Maximum item count reached.' );
}
const instanceInfo = {
visible: true,
active: true,
geometryIndex: geometryId,
};
let drawId = null;
// Prioritize using previously freed instance ids
if ( this._availableInstanceIds.length > 0 ) {
this._availableInstanceIds.sort( ascIdSort );
drawId = this._availableInstanceIds.shift();
this._instanceInfo[ drawId ] = instanceInfo;View on GitHub (pinned to da05705fa3)
Solutions
- Construct BatchedMesh with a maxInstanceCount large enough for the maximum expected instances (plus headroom).
- Recycle instances: call deleteInstance() for dead entities before adding new ones.
- If the cap is structurally wrong, rebuild the BatchedMesh with a larger maxInstanceCount (call setInstanceCount to grow it, or recreate).
Example fix
// before const batch = new BatchedMesh( 100, vertexCount ); for ( let i = 0; i < 150; i ++ ) batch.addInstance( geomId ); // throws at 100 // after const batch = new BatchedMesh( 200, vertexCount ); for ( let i = 0; i < 150; i ++ ) batch.addInstance( geomId );
Defensive patterns
Strategy: validation
Validate before calling
function canAddInstance( batch ) {
const atCapacity = batch._instanceInfo.length >= batch.maxInstanceCount;
return ! atCapacity || batch._availableInstanceIds.length > 0;
}
if ( ! canAddInstance( batch ) ) throw new Error( 'BatchedMesh is at capacity; delete instances or raise maxInstanceCount.' ); Type guard
const hasInstanceCapacity = ( batch ) => canAddInstance( batch );
Try / catch
try {
batch.addInstance( geometryId );
} catch ( e ) {
if ( /Maximum item count reached/.test( e.message ) ) {
batch.deleteInstance( recycledId ); // free a slot then retry
batch.addInstance( geometryId );
} else throw e;
} Prevention
- Size maxInstanceCount with headroom for peak entity count.
- Recycle dead instances via deleteInstance() before adding new ones.
- Grow the batch (setInstanceCount or recreate) if the cap is structurally too low.
When it happens
Trigger: Calling addInstance() more than maxInstanceCount times without deleting any; constructing BatchedMesh with too small a maxInstanceCount for the scene; deleting nothing and continuing to add.
Common situations: Underestimating instance count at construction; growing a scene beyond the pre-allocated batch size; spawning entities dynamically without freeing dead ones.
Related errors
- THREE.BatchedMesh: Invalid instanceId ${instanceId}. Instanc
- THREE.PassNode: Depth texture is not available for this pass
- THREE.WebGPURenderer: Shadow map type not supported yet.
- THREE.ReflectorNode: Depth node can only be requested when t
- THREE.BatchedMesh: All geometries must consistently have "in
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/562b838a014aa187.
Report an issue: GitHub.