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

  1. Construct BatchedMesh with larger maxVertexCount/maxIndexCount sized to the sum of all geometries you will add (plus headroom).
  2. 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.
  3. Before adding, verify (batchedMesh.geometrySize) or track current usage and call setGeometrySize() to grow the buffers when near capacity.
  4. 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

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


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/ddeb86f8ab802a59. Report an issue: GitHub.