stride3d/stride · error · ArgumentException
Invalid sizeof(T), not a multiple of current size
Error message
Invalid sizeof(T), not a multiple of current size [{0}]in bytes What it means
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.
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.
Example fix
// before var pixels = r8Buffer.GetPixels<Rgba32>(); // 1 byte/pixel, not divisible // after var pixels = r8Buffer.GetPixels<byte>(); // then expand to Rgba32 manually
Defensive patterns
Strategy: validation
Validate before calling
int total = buf.Width * buf.Height * bytesPerPixel(buf.Format);
if (total % Unsafe.SizeOf<T>() != 0)
throw new ArgumentException($"sizeof(T)={Unsafe.SizeOf<T>()} does not divide total byte size {total}"); Type guard
bool CanReadAs<T>(PixelBuffer buf) where T : struct =>
(buf.Width * buf.Height * bytesPerPixel(buf.Format)) % Unsafe.SizeOf<T>() == 0; Try / catch
try { return buf.GetPixels<T>(); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Invalid sizeof(T)")) { return buf.GetPixels<byte>(); } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
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
- Pointer cannot be equal to IntPtr.Zero
- Invalid destination pixelBufferArray. Must have the same…
- Should be a multiple of 4.
- size needs to be a multiple of constant buffer alignment
- Cannot copy data between GraphicsResources of types
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/76ed575ff83a427c.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Foundation/Graphics/PixelBuffer.cs:234
=> Unsafe.WriteUnaligned((byte*)DataPointer + RowStride * y + x * PixelSize, value);
/// <summary>
/// Gets scanline pixels from the buffer.
/// </summary>
/// <typeparam name="T">Type of the pixel data</typeparam>
/// <param name="yOffset">The y line offset.</param>
/// <returns>Scanline pixels from the buffer</returns>
/// <exception cref="System.ArgumentException">If the sizeof(T) is an invalid size</exception>
/// <remarks>
/// This method is working on a row basis. The <paramref name="yOffset"/> is specifying the first row to get
/// the pixels from.
/// </remarks>
public T[] GetPixels<T>(int yOffset = 0) where T : struct
{
var sizeOfOutputPixel = Unsafe.SizeOf<T>();
var totalSize = Width * Height * pixelSize;
if ((totalSize % sizeOfOutputPixel) != 0)
throw new ArgumentException(string.Format("Invalid sizeof(T), not a multiple of current size [{0}]in bytes ", totalSize));
var buffer = new T[totalSize / sizeOfOutputPixel];
GetPixels(buffer, yOffset);
return buffer;
}
/// <summary>
/// Gets scanline pixels from the buffer.
/// </summary>
/// <typeparam name="T">Type of the pixel data</typeparam>
/// <param name="pixels">An allocated scanline pixel buffer</param>
/// <param name="yOffset">The y line offset.</param>
/// <returns>Scanline pixels from the buffer</returns>
/// <exception cref="System.ArgumentException">If the sizeof(T) is an invalid size</exception>
/// <remarks>
/// This method is working on a row basis. The <paramref name="yOffset"/> is specifying the first row to get
/// the pixels from.
/// </remarks>View on GitHub (pinned to 96fad776d2)