BabylonJS/Babylon.js · error · RuntimeError

MeshInvalidPositionsError

MeshInvalidPositionsError

Error message

Positions are required

What it means

VertexData._validate() runs during merge (and applyToMesh) and enforces that the VertexData has a positions array; geometry without positions cannot be turned into a mesh. A RuntimeError with code MeshInvalidPositionsError is thrown when positions is null/undefined or empty.

Source

Thrown at packages/dev/core/src/Meshes/mesh.vertexData.ts:1279

                ret[i] = source[i];
            }
            transform && transformRange(ret, transform, 0, source.length);

            let offset = source.length;
            for (const [vertexData, transform] of nonNullOthers) {
                for (let i = 0; i < vertexData.length; i++) {
                    ret[offset + i] = vertexData[i];
                }
                transform && transformRange(ret, transform, offset, vertexData.length);
                offset += vertexData.length;
            }
            return ret;
        }
    }

    private _validate(): void {
        if (!this.positions) {
            throw new RuntimeError("Positions are required", ErrorCodes.MeshInvalidPositionsError);
        }

        const getElementCount = (kind: string, values: FloatArray) => {
            const stride = VertexBufferDeduceStride(kind);
            if (values.length % stride !== 0) {
                throw new Error("The " + kind + "s array count must be a multiple of " + stride);
            }

            return values.length / stride;
        };

        const positionsElementCount = getElementCount(VertexBuffer.PositionKind, this.positions);

        const validateElementCount = (kind: string, values: FloatArray) => {
            const elementCount = getElementCount(kind, values);
            if (elementCount !== positionsElementCount) {
                throw new Error("The " + kind + "s element count (" + elementCount + ") does not match the positions count (" + positionsElementCount + ")");
            }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Ensure every VertexData/mesh in the merge has a non-empty positions array before calling merge
  2. Skip empty meshes in the merge list instead of including them
  3. When building VertexData manually, assign `vertexData.positions = [...]` before merging/applying

Example fix

// before
const empty = new VertexData(); // no positions
vd.merge(empty, true, true, undefined, false); // throws MeshInvalidPositionsError
// after
if (empty.positions && empty.positions.length > 0) {
  vd.merge(empty, true, true, undefined, false);
}
Defensive patterns

Strategy: validation

Validate before calling

function hasPositions(vd: BABYLON.VertexData): boolean {
  return Array.isArray(vd.positions) || (vd.positions instanceof Float32Array && vd.positions.length > 0);
}
if (!hasPositions(vd)) throw new Error("refusing to merge: no positions");

Type guard

const hasValidPositions = (vd: BABYLON.VertexData): vd is BABYLON.VertexData & { positions: number[] | Float32Array } =>
  !!vd.positions && (vd.positions as ArrayLike<number>).length > 0;

Try / catch

import { RuntimeError, ErrorCodes } from "@babylonjs/core";
try {
  vd.applyToMesh(mesh);
} catch (e) {
  if (e instanceof RuntimeError && (e as RuntimeError).errorCode === ErrorCodes.MeshInvalidPositionsError) {
    // rebuild/skip this VertexData
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling vertexData.merge(other, ...) or mergedVertexData._mergeCoroutine result validation when one of the VertexData objects (or the accumulated one) has no positions, e.g. an empty mesh or a VertexData built from only normals/uvs.

Common situations: Merging meshes one of which was created empty (MeshBuilder called with zero positions) or whose positions were disposed; constructing VertexData manually and forgetting set positions; deserialization failures leaving positions undefined.

Related errors


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