stride3d/stride · error · ArgumentException
The object must be IDisposable, IReferenceable, or IntPtr
Error message
The object must be IDisposable, IReferenceable, or IntPtr
What it means
ObjectCollector.Add<T> only accepts objects that are IDisposable, implement IReferencable, or are an IntPtr memory handle, because it must know how to release them during disposal. Passing any other object type is rejected with this ArgumentException to keep the collector's cleanup contract sound.
Solutions
- Make the registered type implement IDisposable and put its cleanup in Dispose().
- If it wraps native memory, register the IntPtr handle allocated via MemoryUtilities.Allocate instead.
- If it is a reference-counted Stride object, implement/inherit IReferencable.
- If the object needs no cleanup, do not register it in the collector.
Example fix
// before
collector.Add(new ConfigSnapshot()); // not IDisposable
// after
class ConfigSnapshot : IDisposable { public void Dispose() { ... } }
collector.Add(new ConfigSnapshot()); Defensive patterns
Strategy: type-guard
Validate before calling
if (obj is not IDisposable and not IReferencable and not IntPtr)
throw new InvalidOperationException("Object is not registrable in ObjectCollector"); Type guard
static bool IsCollectible<T>(T o) where T : notnull => o is IDisposable or IReferencable or IntPtr;
Try / catch
try { collector.Add(obj); }
catch (ArgumentException ex) when (ex.ParamName == "objectToDispose")
{
// object type not managed by the collector; handle or register a wrapper
} Prevention
- Only pass IDisposable, IReferencable, or MemoryUtilities-allocated IntPtr values to Add.
- Make resource wrapper classes implement IDisposable by convention.
- Keep POCOs out of dispose collectors; use a plain list for those.
When it happens
Trigger: Calling collector.Add(someObject) where someObject's runtime type implements none of IDisposable, IReferencable, and is not an IntPtr.
Common situations: Registering plain POCOs or service objects in a ComponentBase/Dispose collector by mistake; refactors that drop IDisposable from a registered class; wrapping a resource in a non-disposable adapter.
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
- The memory pointer is invalid. Memory must have been…
- Cannot add an asset with an empty Id
- Cannot add an asset that is already added to another package
- Asset location [ ] must be relative and not absolute (not…
- An asset [ ] with the same location [ ] is already…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/2a48bc91b1416094.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core/ObjectCollector.cs:62
{
disposables ??= [];
}
/// <summary>
/// Adds an object implementing the <see cref="IDisposable"/> or <see cref="IReferencable"/> interfaces,
/// or a <see cref="IntPtr"/> to an object allocated using <see cref="MemoryUtilities.Allocate"/>
/// to the list of the objects to dispose.
/// </summary>
/// <typeparam name="T">The type of the object to add.</typeparam>
/// <param name="objectToDispose">The object to add to the collector to be disposed at a later time.</param>
/// <exception cref="ArgumentException">
/// <paramref name="objectToDispose"/> does not implement the interface <see cref="IDisposable"/>, <see cref="IReferencable"/>,
/// and is not a valid memory pointer allocated by <see cref="MemoryUtilities.Allocate"/>.
/// </exception>
public T Add<T>(T objectToDispose) where T : notnull
{
if (objectToDispose is not (IDisposable or IReferencable or IntPtr))
throw new ArgumentException("The object must be IDisposable, IReferenceable, or IntPtr", nameof(objectToDispose));
// Check memory alignment
if (objectToDispose is IntPtr memoryPtr && !MemoryUtilities.IsAligned(memoryPtr))
throw new ArgumentException("The memory pointer is invalid. Memory must have been allocated with MemoryUtilities.Allocate", nameof(objectToDispose));
EnsureValid();
if (!disposables.Contains(objectToDispose))
disposables.Add(objectToDispose);
return objectToDispose;
}
/// <summary>
/// Removes a disposable object from the list of the objects to dispose.
/// </summary>
/// <typeparam name="T">The type of the object to remove.</typeparam>
/// <param name="objectToDispose">The object to be removed from the list of objects to dispose.</param>View on GitHub (pinned to 96fad776d2)