stride3d/stride · error · ArgumentException

does not match element size ( != )

Error message

{typeof(TSource)} does not match element size ({sizeof(TSource)} != {element.Size})

What it means

InnerRead validates that the generic source type chosen for a PixelFormat matches the element's declared byte size (sizeof(TSource) == element.Size). A mismatch means the format-to-type mapping is inconsistent with the element size in the vertex declaration, so raw reads would be misaligned. It throws ArgumentException immediately to prevent corrupt data or memory overreads.

Solutions

  1. Fix the VertexElement size in the declaration so it matches the actual format's byte size (e.g. 16 for R32G32B32A32_Float)
  2. Regenerate the vertex declaration from the vertex struct layout instead of hand-writing sizes
  3. If writing a custom reader, pick a TSource whose sizeof matches element.Size
  4. Print element.Size and the expected sizeof for the format to find which is wrong

Example fix

// before
new VertexElement("POSITION", 0, PixelFormat.R32G32B32A32_Float, 0, /*size*/ 12) // mismatch
// after
new VertexElement("POSITION", 0, PixelFormat.R32G32B32A32_Float, 0, /*size*/ 16)
Defensive patterns

Strategy: validation

Validate before calling

if (sizeof(Vector4) != element.Size)
    throw new InvalidOperationException($"Element size {element.Size} does not match format type size");

Try / catch

try { InnerRead<...>(dest, reader, element); }
catch (ArgumentException ex) { logger.Error(ex, "Element size mismatch in vertex declaration"); throw; }

Prevention

When it happens

Trigger: Calling a Read overload where the vertex declaration's element Size does not equal the byte size of the type selected for that format, e.g. an element marked R32G32B32A32_Float (16 bytes) but with VertexElement size computed as 12, or a custom declaration with wrong element sizes.

Common situations: Hand-built VertexDeclaration with wrong size fields; edited mesh headers after changing formats without updating sizes; converter/reader generic mismatch when extending the helper.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Graphics/VertexBufferHelper.cs:273

                case PixelFormat.R16G16B16A16_UInt: InnerRead<TSemantic, TReader, UShort4, TDest>(destination, reader, elementData); break;
                case PixelFormat.R8G8B8A8_UInt: InnerRead<TSemantic, TReader, Byte4, TDest>(destination, reader, elementData); break;
                case PixelFormat.R8G8B8A8_UNorm: InnerRead<TSemantic, TReader, Color, TDest>(destination, reader, elementData); break;
                default: throw new NotImplementedException($"Unsupported format when converting vertex element ({elementData.VertexElement.Format})");
            }

            return true;
        }

        return false;
    }

    private unsafe void InnerRead<TConverter, TReader, TSource, TDest>(Span<TDest> destination, TReader reader, VertexElementWithOffset element) 
        where TConverter : IConverter<TSource, TDest> 
        where TSource : unmanaged
        where TReader : IReader<TDest>, allows ref struct
    {
        if (sizeof(TSource) != element.Size)
            throw new ArgumentException($"{typeof(TSource)} does not match element size ({sizeof(TSource)} != {element.Size})");

        var stride = Binding.Declaration.VertexStride;
        var offset = element.Offset;
        var count = Binding.Count;
            
        fixed (byte* ptrSr = DataInner)
        {
            byte* firstElement = ptrSr + offset;
            reader.Read<TConverter, TSource>(firstElement, count, stride, destination);
        }
    }

    /// <summary>
    /// Lower level access to write directly to the vertex buffer
    /// </summary>
    /// <param name="writer">
    /// An implementation of <see cref="IWriter{TDestValue}"/>, implement this interface to write directly into the vertex buffer
    /// while making use of the auto-conversion of the <typeparamref name="TSemantic"/> provided <br/>

View on GitHub (pinned to 96fad776d2)