BabylonJS/Babylon.js · error
No valid mesh was provided for mesh or convex hull shape par
Error message
No valid mesh was provided for mesh or convex hull shape parameter. Please provide a mesh with valid geometry (number of vertices greater than 0).
What it means
PhysicsAggregate._addSizeOptions resolves shape sizing inputs from the constructor options. For MESH, CONVEX_HULL, and HEIGHTFIELD types it needs an actual mesh with vertex data: it takes options.mesh if given, otherwise falls back to the transformNode itself when that node has vertices. If neither is usable (no mesh, or mesh with 0 vertices), it throws because the shape would have no geometry to build from.
Source
Thrown at packages/dev/core/src/Physics/v2/physicsAggregate.ts:247
this._options.pointA = this._options.pointA ?? new Vector3(0, min.y + capRadius, 0);
this._options.pointB = this._options.pointB ?? new Vector3(0, min.y + extents.y - capRadius, 0);
}
break;
case PhysicsShapeType.CYLINDER:
{
const capRadius = extents.x / 2;
this._options.radius = this._options.radius ?? capRadius;
this._options.pointA = this._options.pointA ?? new Vector3(0, min.y, 0);
this._options.pointB = this._options.pointB ?? new Vector3(0, min.y + extents.y, 0);
}
break;
case PhysicsShapeType.MESH:
case PhysicsShapeType.CONVEX_HULL:
case PhysicsShapeType.HEIGHTFIELD:
if (!this._options.mesh && this._hasVertices(this.transformNode)) {
this._options.mesh = this.transformNode as Mesh;
} else if (!this._options.mesh || !this._hasVertices(this._options.mesh)) {
throw new Error(
"No valid mesh was provided for mesh or convex hull shape parameter. Please provide a mesh with valid geometry (number of vertices greater than 0)."
);
}
break;
case PhysicsShapeType.BOX:
this._options.extents = this._options.extents ?? new Vector3(extents.x, extents.y, extents.z);
this._options.rotation = this._options.rotation ?? Quaternion.Identity();
break;
}
}
/**
* Releases the body, shape and material
*/
public dispose(): void {
if (this._nodeDisposeObserver) {
this.body.transformNode.onDisposeObservable.remove(this._nodeDisposeObserver);
this._nodeDisposeObserver = null;
View on GitHub (pinned to 0592b347b8)
Solutions
- Pass an explicit mesh with geometry: new PhysicsAggregate(node, type, { mesh: sourceMesh, ... }, scene).
- Wait for the mesh to finish loading/importing (await ImportMeshAsync / onMeshReady) so vertices exist, then create the aggregate.
- Use a sizing-based shape (BOX, SPHERE, CAPSULE) if you only need approximate collision and have no mesh.
- Check node.getTotalVertices() > 0 before constructing; also ensure the node is a Mesh, not a bare TransformNode.
Example fix
// before
const aggregate = new PhysicsAggregate(emptyNode, PhysicsShapeType.CONVEX_HULL, { mass: 1 }, scene);
// after
await SceneLoader.ImportMeshAsync("", "assets/", "rock.glb", scene);
if (rock.getTotalVertices() > 0) {
const aggregate = new PhysicsAggregate(rock, PhysicsShapeType.CONVEX_HULL, { mass: 1, mesh: rock }, scene);
} Defensive patterns
Strategy: validation
Validate before calling
if (!(node instanceof Mesh) || node.getTotalVertices() === 0) {
throw new Error("PhysicsAggregate with MESH/CONVEX_HULL/HEIGHTFIELD requires a Mesh with vertices");
}
const aggregate = new PhysicsAggregate(node, PhysicsShapeType.CONVEX_HULL, { mass: 1, mesh: node }, scene); Type guard
function hasVertices(n: TransformNode | AbstractMesh): n is Mesh {
return n instanceof Mesh && n.getTotalVertices() > 0;
} Try / catch
try {
const aggregate = new PhysicsAggregate(node, PhysicsShapeType.CONVEX_HULL, { mass: 1 }, scene);
} catch (e) {
if ((e as Error).message.includes("No valid mesh")) {
console.error("Provide a loaded Mesh with vertices or use a BOX/SPHERE shape instead", e);
}
throw e;
} Prevention
- Create physics aggregates only after mesh assets finish loading (await imports).
- Ensure the node is a Mesh with vertices; plain TransformNodes cannot back a mesh shape.
- Prefer explicit { mesh: ... } in options over relying on the transformNode fallback.
- Use BOX/SPHERE/CAPSULE shapes when you only need approximate collision.
When it happens
Trigger: new PhysicsAggregate(node, PhysicsShapeType.MESH, options, scene) where options.mesh is null and node is a bare TransformNode or an empty Mesh (getTotalVertices() === 0), i.e. the else-if at physicsAggregate.ts:247.
Common situations: Attaching a mesh physics shape to a plain TransformNode or camera; creating the aggregate before the mesh's vertices load (async glTF import not awaited); instanced/thin instances where the source mesh has no vertices; passing a GUI or particle object instead of a Mesh.
Related errors
- Draco: Missing position attribute for encoding.
- The mesh must at least have positions and indices
- No mesh provided to create physics shape.
- Sample2DRgbaToRef: widthPx and heightPx must be positive.
- At least one mesh is needed to create the nav mesh.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/b5a3feb968a7751e.
Report an issue: GitHub.