stride3d/stride · error · InvalidOperationException

Non-matching vertex buffer declarations.

Error message

Non-matching vertex buffer declarations.

What it means

MergeDrawData merges multiple MeshDrawData into one, and requires every mesh to declare an identical vertex buffer layout. This error is thrown when a candidate mesh has a different NUMBER of vertex buffers than the first mesh in the merge group. The library can only concatenate meshes whose vertex buffer declarations match exactly.

Solutions

  1. Ensure all meshes destined for merging have the same VertexBuffers.Length; rebuild meshes into a single interleaved vertex buffer if needed
  2. Exclude the offending mesh from the merge group (check IsSimple and buffer count before adding)
  3. Normalize buffer declarations by copying vertex data into a new VertexBufferBinding with the same declaration as the first mesh

Example fix

// before
mergeList.Add(meshWithTwoBuffers);
MergeExtensions.MergeDrawData(mergeList);
// after
if (mesh.VertexBuffers.Length == firstMesh.VertexBuffers.Length)
    mergeList.Add(mesh);
else
    ConvertToSingleVertexBuffer(mesh); // re-interleave into one buffer
Defensive patterns

Strategy: validation

Validate before calling

bool canMerge = meshes.All(m => m.IsSimple()
    && m.VertexBuffers.Length == meshes[0].VertexBuffers.Length);

Type guard

static bool HasMatchingBufferCount(MeshDrawData m, MeshDrawData first) =>
    m.VertexBuffers != null && m.VertexBuffers.Length == first.VertexBuffers.Length;

Try / catch

try { MergeDrawData(meshes); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Non-matching vertex buffer")) {
    // split meshes into groups by buffer count and merge each group
}

Prevention

When it happens

Trigger: Calling MergeDrawData (via GroupDrawData) on a set of MeshDrawData where meshDrawData.VertexBuffers.Length differs from firstMeshDrawData.VertexBuffers.Length (e.g. first mesh has 1 vertex buffer, another has 2).

Common situations: Mixing meshes built with interleaved single-buffer layouts with meshes split into separate position/normal/uv buffers; merging procedurally generated meshes with meshes loaded from different pipeline stages; model importers that emit different buffer counts per material.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/70e0974781741666. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Rendering/Extensions/MergeExtensions.cs:52

            var firstVertexBuffer = firstMeshDrawData.VertexBuffers[0];
            var hasIndexBuffer = IsIndexed(meshDrawDatas);
            int totalVertexCount = 0;
            int totalIndexCount = 0;

            //TODO: extend to non-simple vertex declarations, fill with default values it missing declarations etc. ?

            for (int i = 0; i < meshDrawDatas.Count; i++)
            {
                var meshDrawData = meshDrawDatas[i];

                // This should not happen anymore
                if (i != 0)
                {
                    if (!meshDrawData.IsSimple())
                        throw new InvalidOperationException("Can only merge simple MeshDrawData.");

                    if (meshDrawData.VertexBuffers.Length != firstMeshDrawData.VertexBuffers.Length)
                        throw new InvalidOperationException("Non-matching vertex buffer declarations.");

                    if (!meshDrawData.VertexBuffers[0].Declaration.Equals(firstMeshDrawData.VertexBuffers[0].Declaration))
                        throw new InvalidOperationException("Non-matching vertex buffer declarations.");
                }

                if (meshDrawData.PrimitiveType != PrimitiveType.TriangleList)
                    throw new InvalidOperationException("Can only merge TriangleList.");

                // Update vertex/index counts
                totalVertexCount += meshDrawData.VertexBuffers[0].Count;
                if (hasIndexBuffer)
                {
                    if (meshDrawData.IndexBuffer != null)
                        totalIndexCount += meshDrawData.IndexBuffer.Count;
                    else
                        totalIndexCount += meshDrawData.VertexBuffers[0].Count;
                }
            }

View on GitHub (pinned to 96fad776d2)