{"record":{"id":"76ed575ff83a427c","repo":"stride3d/stride","slug":"invalid-sizeof-t-not-a-multiple-of-current-size-0-in-bytes","errorCode":null,"errorMessage":"Invalid sizeof(T), not a multiple of current size [{0}]in bytes ","messagePattern":"Invalid sizeof\\(T\\), not a multiple of current size \\[(.+?)\\]in bytes ","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Foundation/Graphics/PixelBuffer.cs","lineNumber":234,"sourceCode":"            => Unsafe.WriteUnaligned((byte*)DataPointer + RowStride * y + x * PixelSize, value);\n\n        /// <summary>\n        /// Gets scanline pixels from the buffer.\n        /// </summary>\n        /// <typeparam name=\"T\">Type of the pixel data</typeparam>\n        /// <param name=\"yOffset\">The y line offset.</param>\n        /// <returns>Scanline pixels from the buffer</returns>\n        /// <exception cref=\"System.ArgumentException\">If the sizeof(T) is an invalid size</exception>\n        /// <remarks>\n        /// This method is working on a row basis. The <paramref name=\"yOffset\"/> is specifying the first row to get\n        /// the pixels from.\n        /// </remarks>\n        public T[] GetPixels<T>(int yOffset = 0) where T : struct\n        {\n            var sizeOfOutputPixel = Unsafe.SizeOf<T>();\n            var totalSize = Width * Height * pixelSize;\n            if ((totalSize % sizeOfOutputPixel) != 0)\n                throw new ArgumentException(string.Format(\"Invalid sizeof(T), not a multiple of current size [{0}]in bytes \", totalSize));\n\n            var buffer = new T[totalSize / sizeOfOutputPixel];\n            GetPixels(buffer, yOffset);\n            return buffer;\n        }\n\n        /// <summary>\n        /// Gets scanline pixels from the buffer.\n        /// </summary>\n        /// <typeparam name=\"T\">Type of the pixel data</typeparam>\n        /// <param name=\"pixels\">An allocated scanline pixel buffer</param>\n        /// <param name=\"yOffset\">The y line offset.</param>\n        /// <returns>Scanline pixels from the buffer</returns>\n        /// <exception cref=\"System.ArgumentException\">If the sizeof(T) is an invalid size</exception>\n        /// <remarks>\n        /// This method is working on a row basis. The <paramref name=\"yOffset\"/> is specifying the first row to get\n        /// the pixels from.\n        /// </remarks>","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Foundation/Graphics/PixelBuffer.cs#L216-L252","documentation":"GetPixels<T> reinterprets the buffer's raw bytes as an array of T, which requires the total byte size (Width * Height * pixelSize) to be evenly divisible by sizeof(T). If it is not, the reinterpreted array length would be fractional, so GetPixels throws ArgumentException with the total byte size in the message.","triggerScenarios":"Calling pixelBuffer.GetPixels<T>() where Width*Height*pixelSize % Unsafe.SizeOf<T>() != 0 — e.g. GetPixels<byte4-equivalent>/GetPixels<float> on an R8_UNorm (1 byte/pixel) buffer, or GetPixels<Color> on a 3-byte-per-pixel format.","commonSituations":"Reading single-channel (R8_UNorm) or A8_UNorm images as 4-byte color structs; padding-packed formats like 3-byte RGB read as half/float; generic helper code that assumes 32bpp everywhere.","solutions":["Use a T whose size divides the total byte size (e.g. GetPixels<byte> for R8_UNorm).","Convert the buffer to a 32bpp format first, then call GetPixels<Rgba32>-equivalent.","Compute expected divisibility with width*height*4 for your format and pick T accordingly."],"exampleFix":"// before\nvar pixels = r8Buffer.GetPixels<Rgba32>(); // 1 byte/pixel, not divisible\n// after\nvar pixels = r8Buffer.GetPixels<byte>(); // then expand to Rgba32 manually","handlingStrategy":"validation","validationCode":"int total = buf.Width * buf.Height * bytesPerPixel(buf.Format);\nif (total % Unsafe.SizeOf<T>() != 0)\n    throw new ArgumentException($\"sizeof(T)={Unsafe.SizeOf<T>()} does not divide total byte size {total}\");","typeGuard":"bool CanReadAs<T>(PixelBuffer buf) where T : struct =>\n    (buf.Width * buf.Height * bytesPerPixel(buf.Format)) % Unsafe.SizeOf<T>() == 0;","tryCatchPattern":"try { return buf.GetPixels<T>(); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Invalid sizeof(T)\")) { return buf.GetPixels<byte>(); }","preventionTips":["Map each PixelFormat to its byte-per-pixel size in a table and pick T from it.","Only read as T when bytesPerPixel formats divide evenly (e.g. Rgba32 for 4bpp formats).","Add unit tests covering GetPixels for every supported format."],"tags":["graphics","pixel-buffer","type-mismatch","alignment"],"backgroundTag":"type-mismatch","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}