mrdoob/three.js · error · Error
THREE.BatchedMesh: Reserved space request exceeds the maximu
Error message
THREE.BatchedMesh: Reserved space request exceeds the maximum buffer size.
What it means
Thrown by BatchedMesh.addGeometry() when the requested vertex/index reservation does not fit in the backing buffers. AddGeometry reserves a contiguous run of the shared attribute/index buffer; if the running start pointer plus the requested reservation exceeds _maxVertexCount or _maxIndexCount, the reservation is rejected. Note operator precedence: the vertex overflow is always checked, while the index overflow is only checked when the geometry has an index.
Source
Thrown at src/objects/BatchedMesh.js:672
geometryInfo.vertexStart = this._nextVertexStart;
geometryInfo.reservedVertexCount = reservedVertexCount === - 1 ? geometry.getAttribute( 'position' ).count : reservedVertexCount;
const index = geometry.getIndex();
const hasIndex = index !== null;
if ( hasIndex ) {
geometryInfo.indexStart = this._nextIndexStart;
geometryInfo.reservedIndexCount = reservedIndexCount === - 1 ? index.count : reservedIndexCount;
}
if (
geometryInfo.indexStart !== - 1 &&
geometryInfo.indexStart + geometryInfo.reservedIndexCount > this._maxIndexCount ||
geometryInfo.vertexStart + geometryInfo.reservedVertexCount > this._maxVertexCount
) {
throw new Error( 'THREE.BatchedMesh: Reserved space request exceeds the maximum buffer size.' );
}
// update id
let geometryId;
if ( this._availableGeometryIds.length > 0 ) {
this._availableGeometryIds.sort( ascIdSort );
geometryId = this._availableGeometryIds.shift();
geometryInfoList[ geometryId ] = geometryInfo;
} else {
geometryId = this._geometryCount;
this._geometryCount ++;
geometryInfoList.push( geometryInfo );View on GitHub (pinned to da05705fa3)
Solutions
- Construct BatchedMesh with larger maxVertexCount/maxIndexCount sized to the sum of all geometries you will add (plus headroom).
- Pass an explicit reservedVertexCount/reservedIndexCount to addGeometry sized to the largest geometry variant you will swap in later, instead of relying on the -1 default.
- Before adding, verify (batchedMesh.geometrySize) or track current usage and call setGeometrySize() to grow the buffers when near capacity.
- If reservations are fragmented, remove unused geometries (deleteGeometry) to reclaim their slots before adding new ones.
Example fix
// before const batch = new THREE.BatchedMesh( 10, 1000, 1000 ); // too small for real assets batch.addGeometry( loadedMesh.geometry ); // throws when verts > 1000 // after const batch = new THREE.BatchedMesh( 10, 200000, 400000 ); batch.addGeometry( loadedMesh.geometry, loadedMesh.geometry.attributes.position.count, loadedMesh.geometry.index ? loadedMesh.geometry.index.count : 0 );
Defensive patterns
Strategy: validation
Validate before calling
// Before addGeometry, confirm the reservation fits.
function canAddGeometry( batchedMesh, geometry, reservedVertexCount = -1, reservedIndexCount = -1 ) {
const posCount = geometry.attributes.position.count;
const resV = reservedVertexCount === -1 ? posCount : reservedVertexCount;
const idx = geometry.getIndex();
const nextV = batchedMesh._nextVertexStart; // or track externally
if ( nextV + resV > batchedMesh.vertexCount ) return false;
if ( idx ) {
const resI = reservedIndexCount === -1 ? idx.count : reservedIndexCount;
if ( batchedMesh._nextIndexStart + resI > batchedMesh.indexCount ) return false;
}
return true;
} Prevention
- Pre-size BatchedMesh capacity to the summed vertex/index counts of all planned geometries plus headroom.
- Always pass explicit reservedVertexCount/reservedIndexCount sized to the largest variant you will swap in.
- Track running usage externally and call setGeometrySize() to grow before exhaustion.
- Reclaim slots via deleteGeometry before adding new geometries when the buffer is fragmented.
When it happens
Trigger: Calling batchedMesh.addGeometry(geometry, reservedVertexCount, reservedIndexCount) where reservedVertexCount defaults to geometry's position count (or a custom value) that, combined with _nextVertexStart, exceeds maxVertexCount; OR an indexed geometry whose _nextIndexStart + reservedIndexCount exceeds maxIndexCount. Also triggered after many addGeometry calls have filled the buffer.
Common situations: Constructing BatchedMesh with a too-small vertexCount/indexCount for the assets you load; loading GLTF models whose geometry is larger than the default reservation; growing content at runtime without pre-sizing the batch; forgetting that reservedVertexCount=-1 uses the full attribute count, not a small default.
Related errors
- THREE.BatchedMesh: Reserved space not large enough for provi
- THREE.BufferAttribute: array should be a Typed Array.
- THREE.BatchedMesh: All geometries must consistently have "in
- THREE.BatchedMesh: Added geometry missing "${ attributeName
- THREE.BatchedMesh: All attributes must have a consistent ite
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/ddeb86f8ab802a59.
Report an issue: GitHub.