{"record":{"id":"1a2dcc8bce6daa97","repo":"stride3d/stride","slug":"indexcountarg-must-be-0","errorCode":null,"errorMessage":"indexCountArg must be >= 0","messagePattern":"indexCountArg must be >= 0","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/VertexHelper.cs","lineNumber":237,"sourceCode":"        /// <summary>\n        /// Generate Tangent BiNormal from an existing vertex/index buffer.\n        /// </summary>\n        /// <param name=\"vertexDeclaration\">The vertex declaration of the vertex buffer passed by parameters.</param>\n        /// <param name=\"vertexBufferData\">The vertex buffer.</param>\n        /// <param name=\"vertexCount\">The vertex count.</param>\n        /// <param name=\"vertexOffset\">The vertex offset.</param>\n        /// <param name=\"vertexStride\">The vertex stride. If 0, It takes the stride from the vertex declaration</param>\n        /// <param name=\"indexData\">The index data.</param>\n        /// <param name=\"is32BitIndex\">if set to <c>true</c> [is32 bit index].</param>\n        /// <param name=\"indexCountArg\">The index count argument.</param>\n        /// <returns>A new vertex buffer with its new layout.</returns>\n        public static unsafe VertexTransformResult GenerateTangentBinormal(VertexDeclaration vertexDeclaration, IntPtr vertexBufferData, int vertexCount, int vertexOffset, int vertexStride, IntPtr indexData, bool is32BitIndex, int indexCountArg)\n        {\n            if (vertexDeclaration == null) throw new ArgumentNullException(\"vertexDeclaration\");\n            if (vertexBufferData == IntPtr.Zero) throw new ArgumentNullException(\"vertexBufferData\");\n            if (vertexCount <= 0) throw new ArgumentOutOfRangeException(\"vertexCount\", \"vertexCount must be > 0\");\n            if (vertexStride < 0) throw new ArgumentOutOfRangeException(\"vertexStride\", \"vertexStride must be >= 0\");\n            if (indexData != IntPtr.Zero && indexCountArg < 0) throw new ArgumentOutOfRangeException(\"indexCountArg\", \"indexCountArg must be >= 0\");\n\n            // Get the stride from the vertex declaration if necessary\n            if (vertexStride == 0)\n            {\n                vertexStride = vertexDeclaration.VertexStride;\n            }\n\n            var indexBufferBinding = indexData;\n\n            var oldVertexStride = vertexStride;\n            var bufferData = vertexBufferData;\n\n            // TODO: Usage index in key\n            var offsetMapping = vertexDeclaration\n                .EnumerateWithOffsets()\n                .ToDictionary(x => x.VertexElement.SemanticAsText, x => x.Offset);\n\n            var positionOffset = offsetMapping[\"POSITION\"];","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/VertexHelper.cs#L219-L255","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nint indexCount = endIndex - startIndex; // -1 when indices missing\nGenerateTangentBinormal(decl, ptr, count, 0, stride, indexPtr, true, indexCount);\n\n// after\nGenerateTangentBinormal(decl, ptr, count, 0, stride, indexPtr, true, indices.Length);","handlingStrategy":"validation","validationCode":"if (indexData != IntPtr.Zero && indexCountArg < 0) throw new InvalidOperationException(\"indexCountArg must be >= 0 when an index buffer is supplied\");","typeGuard":"bool IsValidIndexCount(nint indexData, int count) => indexData == IntPtr.Zero || count >= 0;","tryCatchPattern":"try { GenerateTangentBinormal(decl, ptr, count, 0, stride, indexPtr, true, indexCount); }\ncatch (ArgumentOutOfRangeException ex) { log.Error(\"Negative index count; use the real buffer length\", ex); }","preventionTips":["Always pass indexBuffer.Length as indexCountArg","Avoid -1 sentinels leaking into count parameters","Pass IntPtr.Zero for indexData when the mesh is non-indexed"],"tags":["graphics","argument-out-of-range","index-buffer"],"backgroundTag":"argument-out-of-range","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}