stride3d/stride · error · ArgumentException
Binding describes an array larger than dataOuter
Error message
Binding describes an array larger than dataOuter ({dataOuter.Length} < {binding.Offset} + {binding.Count} * {binding.Stride}) What it means
The VertexBufferHelper constructor throws ArgumentException when the backing byte array (dataOuter) is smaller than the vertex buffer binding requires: binding.Offset + binding.Count * binding.Stride. The helper will read the entire vertex buffer from the array, so the array must contain at least that many bytes. The library throws immediately in the constructor to prevent out-of-bounds reads later.
Solutions
- Re-fetch the full vertex buffer data so dataOuter contains at least binding.Offset + binding.Count * binding.Stride bytes
- Verify VertexBufferBinding values: Offset, Count (number of vertices) and Stride match the actual data array size
- If you only have partial data, reduce binding.Count to (dataOuter.Length - binding.Offset) / binding.Stride
- Log dataOuter.Length and the computed required size to see which side of the mismatch is wrong
Example fix
// before
var helper = new VertexBufferHelper(binding, partialData, out count);
// after
int required = binding.Offset + binding.Count * binding.Stride;
if (partialData.Length < required)
throw new InvalidOperationException($"Need {required} bytes, have {partialData.Length}");
var helper = new VertexBufferHelper(binding, partialData, out count); Defensive patterns
Strategy: validation
Validate before calling
int required = binding.Offset + binding.Count * binding.Stride;
if (data.Length < required)
throw new InvalidOperationException($"Vertex data too small: {data.Length} < {required}"); Type guard
static bool BufferFitsBinding(VertexBufferBinding b, byte[] data) => data.Length >= b.Offset + b.Count * b.Stride;
Try / catch
try { var helper = new VertexBufferHelper(binding, data, out var count); ... }
catch (ArgumentException ex) { logger.Error(ex, "Vertex buffer smaller than binding describes"); throw; } Prevention
- Always size byte arrays from binding.Offset + Count * Stride
- Never reuse truncated GPU readback buffers
- Assert buffer sizes right after fetching data from the GPU
When it happens
Trigger: Constructing VertexBufferHelper with a byte[] retrieved from the GPU that was truncated, or with a binding whose Count/Offset/Stride describe more data than the array holds (e.g. binding.Count set to the element count while the array only holds part of the buffer).
Common situations: Manually rebuilding a vertex buffer after editing mesh data without resizing the byte array; mixing up element count vs byte count when filling VertexBufferBinding; a serializer that truncated the buffer data.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid Z slice index
- does not match element size ( != )
- destination length does not match the amount of vertices…
- The length and stride of destination does not match the…
- The length and stride of source does not match the vertices…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/58fe208744997378.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/VertexBufferHelper.cs:54
public Span<byte> DataInner => DataOuter.AsSpan(Binding.Offset, Binding.Count * Binding.Stride);
/// <inheritdoc cref="MeshExtension.AsReadable(VertexBufferBinding, IServiceRegistry, out VertexBufferHelper, out int)"/>
public VertexBufferHelper(VertexBufferBinding binding, IServiceRegistry services, out int count)
: this(binding, MeshExtension.FetchBufferContentOrThrow(binding.Buffer, services), out count)
{
}
/// <summary>
/// Create the helper from existing data instead of trying to fetch the buffer automatically
/// </summary>
/// <exception cref="ArgumentException">
/// <paramref name="dataOuter"/> does not match the binding definition provided,
/// <paramref name="dataOuter"/> must be the entire vertex buffer
/// </exception>
public VertexBufferHelper(VertexBufferBinding binding, byte[] dataOuter, out int count)
{
if (dataOuter.Length < binding.Offset + binding.Count * binding.Stride)
throw new ArgumentException($"Binding describes an array larger than {nameof(dataOuter)} ({dataOuter.Length} < {binding.Offset} + {binding.Count} * {binding.Stride})");
DataOuter = dataOuter;
Binding = binding;
count = Binding.Count;
}
/// <summary>
/// Extract individual element from each vertex contained in this vertex buffer and copies them into <paramref name="buffer"/>
/// </summary>
/// <param name="buffer">
/// The buffer which will be written to, must have exactly the same amount of items as there are <b>vertices</b> in the buffer
/// </param>
/// <param name="semanticIndex">
/// The semantic to read with that index, starts at zero.<br/>
/// For example, to sample the second TextureCoordinate, you would use
/// <code>
/// <![CDATA[
/// helper.Copy<TextureCoordinateSemantic, Vector2>(myUvs, 1);View on GitHub (pinned to 96fad776d2)