stride3d/stride · error · ArgumentException
The object is not an IEnumerable
Error message
The object is not an IEnumerable
What it means
ReferenceEnumerable.Refresh rebuilds the child references of a collection node. It retrieves the current value from the owner node and requires it to implement IEnumerable, since enumerable references only make sense for lists/dictionaries/sets/collections. If the node's value is not an IEnumerable (e.g. it changed to a scalar), it throws ArgumentException naming ownerNode.
Solutions
- Ensure the owner node's value implements IEnumerable before refreshing: check ownerNode.Retrieve() is IEnumerable.
- If the value legitimately changed to a non-collection, dispose/replace the ReferenceEnumerable rather than refreshing it.
- Fix the source property so its type stays a collection type for the lifetime of this reference.
Example fix
// before
((ReferenceEnumerable)node.References[0]).Refresh(node, nodeContainer);
// after
if (node.Retrieve() is IEnumerable)
((ReferenceEnumerable)node.References[0]).Refresh(node, nodeContainer); Defensive patterns
Strategy: type-guard
Validate before calling
if (ownerNode.Retrieve() is IEnumerable)
enumerableReference.Refresh(ownerNode, nodeContainer); Type guard
bool CanRefresh(IGraphNode node) => node.Retrieve() is IEnumerable;
Try / catch
try { reference.Refresh(ownerNode, nodeContainer); }
catch (ArgumentException ex) when (ex.ParamName == "ownerNode") { /* value stopped being a collection; rebuild the reference instead */ } Prevention
- Keep a node's value a collection type for the reference's lifetime
- Re-create the reference rather than refreshing when the value's shape changes
- Guard refreshes on type before calling
When it happens
Trigger: Calling ReferenceEnumerable.Refresh(ownerNode, nodeContainer) when ownerNode.Retrieve() returns an object that does not implement IEnumerable — e.g. the underlying property was reassigned from a List<T> to a scalar or non-collection object.
Common situations: Data-binding scenarios where an observable property changes type at runtime; node rebuild logic in custom NodeContainers; mutation of graph content from outside Quantum's expected contracts.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- objectValue type does not match objectType
- Two bundles with name
- Could not find dependency
- content reference(s) were not rooted (see errors above)…
- Could not find asset
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/7d24f148ba7d37f8.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Quantum/References/ReferenceEnumerable.cs:65
/// <inheritdoc/>
public ObjectReference this[NodeIndex index] => items[index];
/// <summary>
/// Indicates whether the reference contains the given index.
/// </summary>
/// <param name="index">The index to check.</param>
/// <returns><c>True</c> if the reference contains the given index, <c>False</c> otherwise.</returns>
/// <remarks>If it is an <see cref="ObjectReference"/> it will return true only for <c>null</c>.</remarks>
public bool HasIndex(NodeIndex index)
{
return items?.ContainsKey(index) ?? false;
}
public void Refresh(IGraphNode ownerNode, NodeContainer nodeContainer)
{
var newObjectValue = ownerNode.Retrieve();
if (newObjectValue is not IEnumerable) throw new ArgumentException("The object is not an IEnumerable", nameof(ownerNode));
ObjectValue = newObjectValue;
var newReferences = new HybridDictionary<NodeIndex, ObjectReference>();
if (IsDictionary)
{
foreach (var item in (IEnumerable)ObjectValue)
{
var key = GetKey(item);
var value = (ObjectReference)Reference.CreateReference(GetValue(item), ElementType, key, true);
newReferences.Add(key, value);
}
}
else
{
var i = 0;
foreach (var item in (IEnumerable)ObjectValue)
{View on GitHub (pinned to 96fad776d2)