stride3d/stride · error · InvalidOperationException
A reference can only be constructed with the method…
Error message
A reference can only be constructed with the method Reference.CreateReference
What it means
Reference constructors require an internal thread-local counter (CreatingReference) to be active; it is incremented only inside Reference.CreateReference. If a Reference-derived object is constructed directly (new ...) outside that factory, CheckReferenceCreationSafeGuard detects the counter is zero and throws InvalidOperationException, enforcing that every reference is created through the factory.
Solutions
- Replace direct construction (new ReferenceEnumerable(...)/new DerivedReference(...)) with a call to Reference.CreateReference.
- If you need collection semantics, pass a value of a list/dictionary/set/collection type to CreateReference so it produces a ReferenceEnumerable.
- Only call the constructor from within Reference.CreateReference (i.e. subclass code inside the library).
Example fix
// before var reference = new ReferenceEnumerable(value, nodeIndex); // after var reference = (ReferenceEnumerable)Reference.CreateReference(value, value.GetType(), nodeIndex, false);
Defensive patterns
Strategy: type-guard
Validate before calling
var reference = value != null ? Reference.CreateReference(value, value.GetType(), index, isMember) : null;
Type guard
bool SafeToConstruct() => Reference.CheckReferenceCreationSafeGuard is only satisfied inside CreateReference; never call constructors directly — always use Reference.CreateReference.
Try / catch
try { var r = Reference.CreateReference(value, type, index, isMember); }
catch (InvalidOperationException) { /* you bypassed the factory; switch to CreateReference */ } Prevention
- Treat Reference constructors as internal-only; always use Reference.CreateReference
- Audit custom NodeFactories/tests for direct `new Reference...`
- Reference obsolete API warnings — the factory contract is enforced by this guard
When it happens
Trigger: Instantiating Reference (or a subclass such as ReferenceEnumerable) directly with `new`, instead of calling Reference.CreateReference; this typically happens in custom factories or tests bypassing the factory.
Common situations: Writing a custom IReference implementation or NodeFactory; unit tests constructing ReferenceEnumerable to inspect item references; code copied from older Stride versions where direct construction was tolerated.
Related errors
- A collection type
- A node of the path is null but is not the last node.
- An error occurred while adding an item to the node, see the…
- An error occurred while adding an item to the node, see the…
- An error occurred while removing an item to the node, see…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/ff7150301a9aeca8.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Quantum/References/Reference.cs:54
{
reference = null;
}
}
--CreatingReference.Value;
return reference;
}
private static bool HasCollectionReference(Type type)
{
return type.IsArray || ListDescriptor.IsList(type) || DictionaryDescriptor.IsDictionary(type) || SetDescriptor.IsSet(type) || CollectionDescriptor.IsCollection(type);
}
internal static void CheckReferenceCreationSafeGuard()
{
if (!CreatingReference.IsValueCreated || CreatingReference.Value == 0)
throw new InvalidOperationException("A reference can only be constructed with the method Reference.CreateReference");
}
}
View on GitHub (pinned to 96fad776d2)