stride3d/stride · error · InvalidOperationException

Invalid Width/Height/Depth/ArraySize for Image 3D

Error message

Invalid Width/Height/Depth/ArraySize for Image 3D

What it means

For Texture3D images, Initialize requires Width > 0, Height > 0, Depth > 0, and ArraySize == 1. Volumetric textures must be truly 3-dimensional, and 3D images cannot be arrayed (ArraySize must be exactly 1).

Solutions

  1. Set ArraySize = 1 for Texture3D images.
  2. Ensure Width, Height, and Depth are all > 0.
  3. If you need an array of 2D slices, use Texture2D with ArraySize > 1 instead.
  4. Validate the source file's depth field before constructing the description.

Example fix

// before
var desc = new ImageDescription { Dimension = TextureDimension.Texture3D, Width = 64, Height = 64, Depth = 64, ArraySize = 4 };
// after
var desc = new ImageDescription { Dimension = TextureDimension.Texture3D, Width = 64, Height = 64, Depth = 64, ArraySize = 1 };
Defensive patterns

Strategy: validation

Validate before calling

if (desc.Dimension == TextureDimension.Texture3D &&
    (desc.Width <= 0 || desc.Height <= 0 || desc.Depth <= 0 || desc.ArraySize != 1))
    throw new ArgumentException("Texture3D requires Width/Height/Depth>0 and ArraySize=1.");

Type guard

null

Try / catch

try { img = Image.New(desc, ptr); }
catch (InvalidOperationException ex) when (ex.Message.Contains("for Image 3D"))
{
    desc.ArraySize = 1;
    img = Image.New(desc, ptr);
}

Prevention

When it happens

Trigger: Creating an Image with Dimension = TextureDimension.Texture3D where any of Width/Height/Depth is <= 0, or where ArraySize was left > 1 or left at a non-1 value copied from a 2D array description.

Common situations: Loading volumetric data where the depth read from the file header is 0; cloning a 2D texture-array description and only changing Dimension to Texture3D (keeping ArraySize = 4); default-initialized descriptions with zeroed dimensions.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/6cf4b153f1be7760. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Foundation/Graphics/Image.cs:800

                case TextureDimension.Texture2D:
                case TextureDimension.TextureCube:
                    if (description.Width <= 0 || description.Height <= 0 || description.Depth != 1 || description.ArraySize == 0)
                        throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 2D");

                    if (description.Dimension == TextureDimension.TextureCube)
                    {
                        if ((description.ArraySize % 6) != 0)
                            throw new InvalidOperationException("TextureCube must have an arraysize = 6");
                    }

                    // Check that miplevels are fine
                    description.MipLevels = CalculateMipLevels(description.Width, description.Height, description.MipLevels);
                    break;

                case TextureDimension.Texture3D:
                    if (description.Width <= 0 || description.Height <= 0 || description.Depth <= 0 || description.ArraySize != 1)
                        throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 3D");

                    // Check that miplevels are fine
                    description.MipLevels = CalculateMipLevels(description.Width, description.Height, description.Depth, description.MipLevels);
                    break;
            }

            // Calculate mipmaps
            mipMapToZIndex = CalculateImageArray(description, pitchFlags, rowStride, out var pixelBufferCount, out totalSizeInBytes);
            mipmapDescriptions = CalculateMipMapDescription(description);
            zBufferCountPerArraySlice = mipMapToZIndex[^1];

            // Allocate all pixel buffers
            PixelBuffers = new PixelBuffer[pixelBufferCount];
            pixelBufferArray = new PixelBufferArray(this);

            // Setup all pointers
            // only release buffer that is not pinned and is asked to be disposed.
            this.bufferIsDisposable = !handle.HasValue && bufferIsDisposable;

View on GitHub (pinned to 96fad776d2)