stride3d/stride · error · ArgumentNullException
array
Error message
array
What it means
Argument-null validation in ArrayPool.Free: the array being returned to the pool is null. There is no pooled object to release for a null reference, so the method throws ArgumentNullException named 'array'. (Note the sibling Allocate method similarly guards size with 'Must be positive'.)
Solutions
- Initialize buffers to Array.Empty<T>() instead of null
- Guard Free calls with a null check
- Ensure allocation succeeded before scheduling the free
Example fix
// before arrayPool.Free(buffer); // buffer may be null // after if (buffer != null) arrayPool.Free(buffer);
Defensive patterns
Strategy: validation
Validate before calling
if (buffer != null)
pool.Free(buffer); Prevention
- Initialize buffers to Array.Empty<T>() not null
- Only free buffers that were successfully allocated
- Null-check in cleanup/finally paths
When it happens
Trigger: Calling Free(null) after a failed allocation path or when the buffer variable was never assigned.
Common situations: Cleanup/finally blocks in particle sorting code freeing buffers that were never allocated.
Related errors
- Must be positive.
- A Gear constraint always needs two rigidbodies to be…
- adapter
- antialiasShaderName
- ArgumentNullException: deletedObjects
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b34aa86273afa1fd.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Particles/Sorters/ArrayPool.cs:31
public virtual void Clear()
{
_pool.Clear();
}
public virtual T[] Allocate(int size)
{
if (size < 0) throw new ArgumentOutOfRangeException(nameof(size), "Must be positive.");
if (size == 0) return Empty;
Stack<T[]> candidates;
return _pool.TryGetValue(size, out candidates) && candidates.Count > 0 ? candidates.Pop() : new T[size];
}
public virtual void Free(T[] array)
{
if (array == null) throw new ArgumentNullException(nameof(array));
if (array.Length == 0) return;
Stack<T[]> candidates;
if (!_pool.TryGetValue(array.Length, out candidates))
_pool.Add(array.Length, candidates = new Stack<T[]>());
candidates.Push(array);
}
}
public class ConcurrentArrayPool<T> : ArrayPool<T> where T : struct
{
public override T[] Allocate(int size)
{
lock (this)
{
return base.Allocate(size);
}View on GitHub (pinned to 96fad776d2)