stride3d/stride · error · ArgumentNullException

unmanagedArray

Error message

unmanagedArray

What it means

UnmanagedArrayExtensions.Fill validates its destination before filling. A null unmanagedArray cannot be written to, so an ArgumentNullException naming the 'unmanagedArray' parameter is thrown. This is a guard against passing an uninitialized native memory buffer.

Solutions

  1. Ensure the UnmanagedArray<T> is allocated before calling Fill
  2. Null-check the array at the call site before filling
  3. Fix the earlier allocation/initialization path that left the array null

Example fix

// before
buffer.Fill(0f, 0, count);
// after
if (buffer != null) buffer.Fill(0f, 0, count);
Defensive patterns

Strategy: type-guard

Validate before calling

if (array == null) throw new InvalidOperationException("UnmanagedArray not allocated");
array.Fill(value, index, fillLength);

Type guard

static bool IsAllocated<T>(UnmanagedArray<T> a) where T : struct => a != null && a.Length > 0;

Try / catch

try { array.Fill(value, index, fillLength); } catch (ArgumentNullException) { /* array was never allocated */ }

Prevention

When it happens

Trigger: Calling unmanagedArray.Fill(value, index, fillLength) as an extension method on a null UnmanagedArray<T> reference, e.g. an array that failed allocation or was never assigned.

Common situations: Native buffer creation failed silently earlier, or a struct field holding the unmanaged array was default-initialized and used before allocation.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Physics/UnmanagedArrayExtensions.cs:20

// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System;
using Stride.Core;

namespace Stride.Physics
{
    public static class UnmanagedArrayExtensions
    {
        /// <summary>
        /// Fill the array with specific value.
        /// </summary>
        /// <typeparam name="T">The type param of UnmanagedArray</typeparam>
        /// <param name="unmanagedArray">The destination to fill.</param>
        /// <param name="value">The value used to fill.</param>
        /// <param name="index">The start index of the destination to fill.</param>
        /// <param name="fillLength">The filling length.</param>
        public static void Fill<T>(this UnmanagedArray<T> unmanagedArray, T value, int index, int fillLength) where T : struct
        {
            if (unmanagedArray == null) throw new ArgumentNullException(nameof(unmanagedArray));

            var length = unmanagedArray.Length;
            var endIndex = index + fillLength;

            if (length <= index) throw new IndexOutOfRangeException(nameof(index));
            if (length < endIndex) throw new ArgumentException($"{ nameof(unmanagedArray) }.{ nameof(unmanagedArray.Length) } is not enough to fill.");

            for (int i = index; i < endIndex; ++i)
            {
                unmanagedArray[i] = value;
            }
        }
    }
}

View on GitHub (pinned to 96fad776d2)