stride3d/stride · error · ArgumentOutOfRangeException
indexCountArg must be >= 0
Error message
indexCountArg must be >= 0
What it means
A validation guard in VertexHelper.GenerateTangentBinormal: indexCountArg (the index count of the buffer used to generate tangents/binormals) is negative. Computing tangent frames iterates over indices; a negative count makes the operation meaningless and would cause invalid memory access, so the method throws an ArgumentOutOfRangeException before touching the buffers.
Solutions
- Pass the actual index count (e.g. indexBuffer.Length) instead of a computed/sentinel value.
- Fix the computation that yields the negative count.
- If there are truly no indices, pass IntPtr.Zero for indexData so the count is not required.
Example fix
// before int indexCount = endIndex - startIndex; // -1 when indices missing GenerateTangentBinormal(decl, ptr, count, 0, stride, indexPtr, true, indexCount); // after GenerateTangentBinormal(decl, ptr, count, 0, stride, indexPtr, true, indices.Length);
Defensive patterns
Strategy: validation
Validate before calling
if (indexData != IntPtr.Zero && indexCountArg < 0) throw new InvalidOperationException("indexCountArg must be >= 0 when an index buffer is supplied"); Type guard
bool IsValidIndexCount(nint indexData, int count) => indexData == IntPtr.Zero || count >= 0;
Try / catch
try { GenerateTangentBinormal(decl, ptr, count, 0, stride, indexPtr, true, indexCount); }
catch (ArgumentOutOfRangeException ex) { log.Error("Negative index count; use the real buffer length", ex); } Prevention
- Always pass indexBuffer.Length as indexCountArg
- Avoid -1 sentinels leaking into count parameters
- Pass IntPtr.Zero for indexData when the mesh is non-indexed
When it happens
Trigger: Calling the IntPtr overload with indexData != IntPtr.Zero and a negative indexCountArg — e.g. an index buffer length computed to a negative value or a bad cast.
Common situations: Computing index count via subtraction/overflow; reusing a variable that was set to -1 as a sentinel; mismatch between indexData size and the count parameter.
Related errors
- Cannot specify the format for more than 8 Render Targets.
- destination length does not match the amount of indices…
- Element size must be set to sizeof(short) = 2 or…
- Invalid array slice index
- Invalid mipmap level
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/1a2dcc8bce6daa97.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/VertexHelper.cs:237
/// <summary>
/// Generate Tangent BiNormal from an existing vertex/index buffer.
/// </summary>
/// <param name="vertexDeclaration">The vertex declaration of the vertex buffer passed by parameters.</param>
/// <param name="vertexBufferData">The vertex buffer.</param>
/// <param name="vertexCount">The vertex count.</param>
/// <param name="vertexOffset">The vertex offset.</param>
/// <param name="vertexStride">The vertex stride. If 0, It takes the stride from the vertex declaration</param>
/// <param name="indexData">The index data.</param>
/// <param name="is32BitIndex">if set to <c>true</c> [is32 bit index].</param>
/// <param name="indexCountArg">The index count argument.</param>
/// <returns>A new vertex buffer with its new layout.</returns>
public static unsafe VertexTransformResult GenerateTangentBinormal(VertexDeclaration vertexDeclaration, IntPtr vertexBufferData, int vertexCount, int vertexOffset, int vertexStride, IntPtr indexData, bool is32BitIndex, int indexCountArg)
{
if (vertexDeclaration == null) throw new ArgumentNullException("vertexDeclaration");
if (vertexBufferData == IntPtr.Zero) throw new ArgumentNullException("vertexBufferData");
if (vertexCount <= 0) throw new ArgumentOutOfRangeException("vertexCount", "vertexCount must be > 0");
if (vertexStride < 0) throw new ArgumentOutOfRangeException("vertexStride", "vertexStride must be >= 0");
if (indexData != IntPtr.Zero && indexCountArg < 0) throw new ArgumentOutOfRangeException("indexCountArg", "indexCountArg must be >= 0");
// Get the stride from the vertex declaration if necessary
if (vertexStride == 0)
{
vertexStride = vertexDeclaration.VertexStride;
}
var indexBufferBinding = indexData;
var oldVertexStride = vertexStride;
var bufferData = vertexBufferData;
// TODO: Usage index in key
var offsetMapping = vertexDeclaration
.EnumerateWithOffsets()
.ToDictionary(x => x.VertexElement.SemanticAsText, x => x.Offset);
var positionOffset = offsetMapping["POSITION"];View on GitHub (pinned to 96fad776d2)