BabylonJS/Babylon.js · error

Cannot merge vertex data that do not have the same set of at

Error message

Cannot merge vertex data that do not have the same set of attributes

What it means

VertexData.merge() requires that all merged VertexData objects expose the same set of vertex attributes (positions, normals/uvs, colors, matricesIndices/Weights and their Extra variants). When `useStridedVertexData` is true and a strict boolean-presence comparison shows one dataset has an attribute another lacks, merging would produce a corrupt buffer, so it throws.

Source

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

            if (!enableCompletion) {
                other._validate();
                if (
                    !this.normals !== !other.normals ||
                    !this.tangents !== !other.tangents ||
                    !this.uvs !== !other.uvs ||
                    !this.uvs2 !== !other.uvs2 ||
                    !this.uvs3 !== !other.uvs3 ||
                    !this.uvs4 !== !other.uvs4 ||
                    !this.uvs5 !== !other.uvs5 ||
                    !this.uvs6 !== !other.uvs6 ||
                    !this.colors !== !other.colors ||
                    !this.matricesIndices !== !other.matricesIndices ||
                    !this.matricesWeights !== !other.matricesWeights ||
                    !this.matricesIndicesExtra !== !other.matricesIndicesExtra ||
                    !this.matricesWeightsExtra !== !other.matricesWeightsExtra
                ) {
                    throw new Error("Cannot merge vertex data that do not have the same set of attributes");
                }
            } else {
                // Align the others with main set of attributes
                if (this.normals && !other.normals) {
                    other.normals = new Float32Array(other.positions!.length);
                }

                if (this.tangents && !other.tangents) {
                    other.tangents = new Float32Array((other.positions!.length / 3) * 4);
                }

                if (this.uvs && !other.uvs) {
                    other.uvs = new Float32Array((other.positions!.length / 3) * 2);
                }

                if (this.uvs2 && !other.uvs2) {
                    other.uvs2 = new Float32Array((other.positions!.length / 3) * 2);
                }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Ensure every mesh being merged has the same vertex kinds: add matching uvs/colors/normals to the deficient meshes (e.g. VertexData computeNormals or set a default color set)
  2. Call merge with useStridedVertexData = false so missing attributes are auto-aligned with zeroed Float32Arrays
  3. Convert meshes so their VertexBuffer kinds match before merging (clone with identical material/vertex setup)

Example fix

// before
const merged = mesh.mergeMeshes([meshA /* no uvs */, meshB /* has uvs */], true, true, undefined, false, true); // throws
// after
const merged = mesh.mergeMeshes([meshA, meshB], true, true, undefined, false, false); // aligns missing attributes automatically
Defensive patterns

Strategy: validation

Validate before calling

function sameKinds(a: BABYLON.VertexData, b: BABYLON.VertexData): boolean {
  const has = (v: BABYLON.VertexData) => ({ pos: !!v.positions, nrm: !!v.normals, uv: !!(v as any).uvs, col: !!v.colors, mi: !!(v as any).matricesIndices, mw: !!(v as any).matricesWeights });
  const ha = has(a), hb = has(b);
  return Object.keys(ha).every(k => ha[k] === hb[k]);
}
if (!sameKinds(vd, other)) {
  // pass useStridedVertexData=false or normalize attributes first
}

Type guard

const hasMatchingAttributes = (a: BABYLON.VertexData, b: BABYLON.VertexData): boolean =>
  (!!a.normals === !!b.normals) && (!!a.colors === !!b.colors) &&
  (!!a.matricesIndices === !!b.matricesIndices) && (!!a.matricesWeights === !!b.matricesWeights);

Try / catch

try {
  merged = mesh.mergeMeshes(list, true, true, undefined, false, true);
} catch (e) {
  if (String((e as Error).message).includes("same set of attributes")) {
    merged = mesh.mergeMeshes(list, true, true, undefined, false, false); // auto-align
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling mesh.mergeMeshes(...) or vertexData.merge(other, dispose, ..., true) where e.g. one mesh has UVs/colors/skin weights and another does not.

Common situations: Merging a mesh that was loaded from a model with vertex colors together with a programmatically created mesh without colors; mixing skinned (matricesWeights) and non-skinned meshes; meshes where one has tangents/uvs and the other was built without them.

Related errors


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