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

  1. Fix the asset: ensure every mesh has at least one primitive (remove empty meshes with gltf-transform prune or similar)
  2. Re-export the model from the DCC tool after cleaning up unused/empty meshes
  3. 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

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


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