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

  1. Use a T whose size divides the total byte size (e.g. GetPixels<byte> for R8_UNorm).
  2. Convert the buffer to a 32bpp format first, then call GetPixels<Rgba32>-equivalent.
  3. 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

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


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)