stride3d/stride · error · InvalidOperationException
Can only merge TriangleList.
Error message
Can only merge TriangleList.
What it means
MergeDrawData only supports merging meshes whose PrimitiveType is TriangleList. This error is thrown when a mesh in the merge group uses any other primitive type (lines, strips, fan, triangle lists with adjacency, etc.), because index/vertex concatenation logic assumes triangle-list topology.
Solutions
- Convert the mesh to TriangleList (expand strips via degenerate-triangle insertion or index rewriting) before merging
- Exclude non-TriangleList meshes from the merge group
- Set meshDrawData.PrimitiveType = PrimitiveType.TriangleList when the underlying data is actually triangle-list
Example fix
// before meshDrawData.PrimitiveType = PrimitiveType.TriangleStrip; MergeDrawData(list); // after meshDrawData.PrimitiveType = PrimitiveType.TriangleList; ConvertStripIndicesToList(meshDrawData); // expand strip indices MergeDrawData(list);
Defensive patterns
Strategy: validation
Validate before calling
bool allTriangleLists = meshes.All(m => m.PrimitiveType == PrimitiveType.TriangleList);
if (!allTriangleLists) throw new InvalidOperationException("Convert strips first."); Type guard
static bool IsTriangleList(MeshDrawData m) => m.PrimitiveType == PrimitiveType.TriangleList;
Try / catch
try { MergeDrawData(meshes); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Can only merge TriangleList")) {
// convert offending meshes or exclude them, then retry
} Prevention
- Normalize all geometry to TriangleList at import time
- Never assign strip/line topologies to meshes destined for batch merging
- Log primitive type when building merge candidate lists
When it happens
Trigger: Calling MergeDrawData (via GroupDrawData) with a MeshDrawData whose PrimitiveType is TriangleStrip, LineList, LineStrip, PointList, or TriangleListWithAdjacency instead of TriangleList.
Common situations: Merging debug line meshes or strip-based geometry with regular triangle meshes; procedurally generated geometry using strips; meshes imported with preserved primitive topology.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Non-matching vertex buffer declarations.
- The mesh Data needs to have index buffer
- Sorting not implemented for multiple vertex buffers by…
- meshData is not simple.
- msaaResolverShaderName
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/68c782a68a4756e1.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Rendering/Extensions/MergeExtensions.cs:59
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;
}
}
// Allocate vertex buffer
var result = new MeshDraw { PrimitiveType = PrimitiveType.TriangleList };
var destBufferData = new byte[firstVertexBuffer.Declaration.VertexStride * totalVertexCount];
result.VertexBuffers = new VertexBufferBinding[]
{
new VertexBufferBinding(View on GitHub (pinned to 96fad776d2)