BabylonJS/Babylon.js · error

The mesh must at least have positions and indices

Error message

The mesh must at least have positions and indices

What it means

CSG2.FromMesh reads position vertices and the index buffer from the mesh's geometry. If either is absent, the mesh has no renderable geometry usable for CSG and this error is thrown before submesh/material mapping begins.

Source

Thrown at packages/dev/core/src/Meshes/csg2.ts:431

            throw new Error("The vertexData must at least have positions and indices");
        }

        return this._Construct(vertexData, null);
    }

    /**
     * Create a new Constructive Solid Geometry from a mesh
     * @param mesh defines the mesh to use to create the CSG
     * @param ignoreWorldMatrix defines if the world matrix should be ignored
     * @returns a new CSG2 class
     */
    public static FromMesh(mesh: Mesh, ignoreWorldMatrix = false): CSG2 {
        const sourceVertices = mesh.getVerticesData(VertexBuffer.PositionKind);
        const sourceIndices = mesh.getIndices();
        const worldMatrix = mesh.computeWorldMatrix(true);

        if (!sourceVertices || !sourceIndices) {
            throw new Error("The mesh must at least have positions and indices");
        }

        // Create a triangle run for each submesh (material)
        const starts = [...Array(mesh.subMeshes.length)].map((_, idx) => mesh.subMeshes[idx].indexStart);

        // Map the materials to ID.
        const sourceMaterial = mesh.material || mesh.getScene().defaultMaterial;
        const isMultiMaterial = sourceMaterial.getClassName() === "MultiMaterial";
        const originalIDs = [...Array(mesh.subMeshes.length)].map((_, idx) => {
            if (isMultiMaterial) {
                return FirstID + (sourceMaterial as MultiMaterial).subMaterials[mesh.subMeshes[idx].materialIndex]!.uniqueId;
            }

            return FirstID + sourceMaterial.uniqueId;
        });

        // List the runs in sequence.
        const indices = Array.from(starts.keys());

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Verify the mesh has geometry: `mesh.getVerticesData(VertexBuffer.PositionKind)` and `mesh.getIndices()` are non-null before calling.
  2. If building from VertexData, call `vertexData.applyToMesh(mesh)` first, or use `CSG2.FromVertexData` directly.
  3. Use a solid (triangle-indexed) mesh as CSG input; lines/points are not valid solids.

Example fix

// before
const empty = new BABYLON.Mesh("empty", scene);
const csg = CSG2.FromMesh(empty); // throws
// after
const box = BABYLON.MeshBuilder.CreateBox("box", { size: 2 }, scene);
const csg = CSG2.FromMesh(box);
Defensive patterns

Strategy: validation

Validate before calling

function canBuildCsgFromMesh(mesh: Mesh): boolean {
  return !!mesh.geometry
    && !!mesh.getVerticesData(VertexBuffer.PositionKind)
    && mesh.getIndices().length > 0;
}
if (!canBuildCsgFromMesh(mesh)) throw new Error(`Mesh '${mesh.name}' lacks positions/indices for CSG`);

Type guard

function hasRenderableGeometry(mesh: Mesh): boolean {
  const pos = mesh.getVerticesData(VertexBuffer.PositionKind);
  return pos != null && pos.length > 0 && mesh.getIndices().length > 0;
}

Prevention

When it happens

Trigger: Calling `CSG2.FromMesh(mesh)` on a mesh created with `new Mesh(...)` but never given geometry (no setVerticesData/Geometry), a mesh whose geometry was disposed, or a Lines/Points mesh with no index buffer.

Common situations: Forgetting to call MeshBuilder creation or applyToMesh on a VertexData; disposing geometry earlier in the frame; targeting thin instances or GPU-picked meshes whose CPU-side geometry was never uploaded; LinesMesh/GroundMesh edge cases without indices.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/1f9c59f0c7445a3a. Report an issue: GitHub.