stride3d/stride · error · InvalidOperationException

Can only merge simple MeshDrawData.

Error message

Can only merge simple MeshDrawData.

What it means

MergeDrawData can only merge 'simple' MeshDraw instances (single vertex buffer, no complex draw data, as determined by IsSimple()). If the first element is not simple, an InvalidOperationException is thrown since multi-buffer or non-simple draws cannot be concatenated.

Solutions

  1. Only pass MeshDraw instances where IsSimple() returns true
  2. Split non-simple meshes into separate draw calls instead of merging
  3. Verify mesh import settings produce simple draws for the batching path

Example fix

// before
var merged = MeshDraw.MergeDrawData(meshDraws, true);
// after
var merged = meshDraws.All(m => m.IsSimple()) ? MeshDraw.MergeDrawData(meshDraws, true) : meshDraws[0];
Defensive patterns

Strategy: validation

Validate before calling

if (meshDrawDatas.Count > 1 && !meshDrawDatas[0].IsSimple())
    return meshDrawDatas[0]; // cannot merge; use as-is
var merged = MeshDraw.MergeDrawData(meshDrawDatas, can32BitIndex);

Type guard

static bool AllSimple(IList<MeshDraw> list) => list.All(m => m.IsSimple());

Try / catch

try { var merged = MeshDraw.MergeDrawData(meshDrawDatas, can32BitIndex); } catch (InvalidOperationException) { /* non-simple MeshDrawData */ }

Prevention

When it happens

Trigger: Passing a MeshDraw with multiple vertex buffers or non-simple structure as the first element of the list to MergeDrawData (e.g. skinned meshes or draws with extra streaming buffers).

Common situations: Merging meshes with different layouts — morph targets, skinning, multiple VBs — into a batched draw.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

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

    public static class MergeExtensions
    {
        /// <summary>
        /// Transform a vertex buffer positions, normals, tangents and bitangents using the given matrix.
        /// </summary>
        /// <param name="meshDrawDatas">The mesh draw datas.</param>
        /// <param name="can32BitIndex">A flag stating if 32 bit index buffers.</param>
        public static unsafe MeshDraw MergeDrawData(IList<MeshDraw> meshDrawDatas, bool can32BitIndex)
        {
            if (meshDrawDatas.Count == 0)
                throw new ArgumentException("Need at least 1 MeshDrawData.", "meshDrawDatas");

            if (meshDrawDatas.Count == 1)
                return meshDrawDatas[0];

            // Check that vertex buffer declarations are matching
            var firstMeshDrawData = meshDrawDatas[0];
            if (!firstMeshDrawData.IsSimple())
                throw new InvalidOperationException("Can only merge simple MeshDrawData.");

            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.");

View on GitHub (pinned to 96fad776d2)