BabylonJS/Babylon.js · error · Error
${context}: Primitives are missing
Error message
${context}: Primitives are missing What it means
A glTF mesh must contain at least one primitive. When _loadMeshAsync encounters a mesh whose 'primitives' array is missing or empty, it throws because there is no geometry to build a Babylon mesh from.
Source
Thrown at packages/dev/loaders/src/glTF/2.0/glTFLoader.pure.ts:1081
return Promise.all(promises).then(() => {
this._forEachPrimitive(node, (babylonMesh) => {
const asMesh = babylonMesh as Mesh;
if (!asMesh.isAnInstance && asMesh.geometry && asMesh.geometry.useBoundingInfoFromGeometry) {
// simply apply the world matrices to the bounding info - the extends are already ok
babylonMesh._updateBoundingInfo();
} else {
babylonMesh.refreshBoundingInfo(true, true);
}
});
return node._babylonTransformNode!;
});
}
private _loadMeshAsync(context: string, node: INode, mesh: IMesh, assign: (babylonTransformNode: TransformNode) => void): Promise<TransformNode> {
const primitives = mesh.primitives;
if (!primitives || !primitives.length) {
throw new Error(`${context}: Primitives are missing`);
}
if (primitives[0].index == undefined) {
ArrayItem.Assign(primitives);
}
const promises = new Array<Promise<unknown>>();
this.logOpen(`${context} ${mesh.name || ""}`);
const name = node.name || `node${node.index}`;
if (primitives.length === 1) {
const primitive = mesh.primitives[0];
promises.push(
this._loadMeshPrimitiveAsync(`${context}/primitives/${primitive.index}`, name, node, mesh, primitive, (babylonMesh) => {
node._babylonTransformNode = babylonMesh;
node._primitiveBabylonMeshes = [babylonMesh];
View on GitHub (pinned to 0592b347b8)
Solutions
- Fix the asset: ensure every mesh has at least one primitive (remove empty meshes with gltf-transform prune or similar)
- Re-export the model from the DCC tool after cleaning up unused/empty meshes
- Edit the glTF JSON to delete the empty mesh and any nodes referencing it
Example fix
// before (in .gltf)
// { "meshes": [ { "name": "empty", "primitives": [] } ] }
// after
// { "meshes": [ { "name": "solid", "primitives": [ { "attributes": { "POSITION": 0 }, "indices": 1 } ] } ] } Defensive patterns
Strategy: validation
Validate before calling
// Check meshes have primitives before loading
const emptyMeshes = (gltf.meshes ?? [])
.map((m, i) => [m, i])
.filter(([m]) => !m.primitives || m.primitives.length === 0)
.map(([, i]) => i);
if (emptyMeshes.length) console.warn(`Meshes without primitives: ${emptyMeshes}`); Type guard
function meshHasPrimitives(mesh) {
return Array.isArray(mesh.primitives) && mesh.primitives.length > 0;
} Try / catch
try {
await loader.loadAsync(url);
} catch (e) {
if (e.message.includes(": Primitives are missing")) {
console.error("Asset contains an empty mesh — prune it with gltf-transform");
} else throw e;
} Prevention
- Validate assets with glTF-Validator before deployment
- Clean up unused/empty meshes in the DCC tool before exporting
- Prune orphan nodes/meshes with gltf-transform prune
When it happens
Trigger: Loading a glTF asset containing a mesh entry like { "primitives": [] } or a mesh with no primitives property at all.
Common situations: Models exported from DCC tools with empty meshes; hand-edited or programmatically generated glTF where primitives were removed; asset-optimization scripts that stripped primitives but left the mesh node.
Related errors
- ${context}: Invalid recursive node hierarchy
- ${context}: Attributes are missing
- ${context}: Primitives do not have the same number of target
- ${context}: Camera perspective properties are missing
- Draco: Missing position attribute for encoding.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/df0d8d4ecaed57d7.
Report an issue: GitHub.