stride3d/stride · error · ArgumentException

The alignment must be a positive power of 2.

Error message

The alignment must be a positive power of 2.

What it means

MemoryUtilities.ThrowAlignmentNotPowerOfTwo is a [DoesNotReturn] helper that throws ArgumentException("The alignment must be a positive power of 2.") with the failing expression as paramName. It is invoked by Allocate and IsAligned when the align parameter is not a positive power of two (must satisfy align > 0 and (align & (align - 1)) == 0). Native/unaligned memory allocation and alignment checks require valid power-of-two alignment.

Solutions

  1. Round the alignment up to the next power of two before calling, or use a fixed valid constant (1, 2, 4, 8, 16, 32, 64...)
  2. Validate input with (align > 0 && (align & (align - 1)) == 0) before invoking Allocate/IsAligned
  3. Replace struct-size-derived alignment with Math.BitOperations.RoundUpToPowerOf2 or a hardcoded natural alignment
  4. Check config/CLI sources supplying the alignment and clamp/validate them at load time

Example fix

// before
var ptr = MemoryUtilities.Allocate(size, sizeof(MyStruct)); // e.g. 12 -> throws
// after
int align = (int)BitOperations.RoundUpToPowerOf2((uint)sizeof(MyStruct)); // 16
var ptr = MemoryUtilities.Allocate(size, align);
Defensive patterns

Strategy: validation

Validate before calling

static bool IsPowerOfTwo(int align) => align > 0 && (align & (align - 1)) == 0;
if (!IsPowerOfTwo(align)) throw new ArgumentOutOfRangeException(nameof(align));

Type guard

static bool IsValidAlignment(int align) =>
    int.IsPow2(align) && align > 0;

Try / catch

try
{
    var ptr = MemoryUtilities.Allocate(size, align);
}
catch (ArgumentException ex) when (ex.ParamName == nameof(align))
{
    // align was not a positive power of two: round up and retry
}

Prevention

When it happens

Trigger: Calling MemoryUtilities.Allocate(size, align) or IsAligned(pointer, align) with align <= 0, or a non-power-of-two value like 3, 6, 24, or 100. Alignment values not representable as 2^n are rejected regardless of size.

Common situations: Passing sizeof(SomeStruct) or Marshal.SizeOf results as alignment (e.g. 12 or 24); hard-coding an alignment like 16 bytes but multiplying it by a SIMD width; configuration values from users that are not validated as powers of two.

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/783c0ec552962ea1. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core/MemoryUtilities.cs:366


    /// <summary>
    ///   Swaps two values.
    /// </summary>
    /// <typeparam name="T">The type of the values to swap.</typeparam>
    /// <param name="left">The left value.</param>
    /// <param name="right">The right value.</param>
    public static void Swap<T>(ref T left, ref T right)
    {
        (right, left) = (left, right);
    }

    #region Throw helpers

    [DoesNotReturn]
    private static bool ThrowAlignmentNotPowerOfTwo(int align, [CallerArgumentExpression(nameof(align))] string? paramName = null)
    {
        throw new ArgumentException("The alignment must be a positive power of 2.", paramName);
    }

    #endregion
}

View on GitHub (pinned to 96fad776d2)