stride3d/stride · error · InvalidOperationException

IsObjectReference returned true for an object that is not…

Error message

IsObjectReference returned true for an object that is not IIdentifiable

What it means

ObjectReferencePathGenerator.VisitMemberNode relies on the graph definition predicate IsObjectReference. When the predicate says a member's value is an object reference, the value must implement IIdentifiable so its Id can be recorded; otherwise the generator's contract is violated and it throws.

Solutions

  1. Make the member's value type implement IIdentifiable (or derive from IdentifiableEntity/Entity) so it has an Id.
  2. Fix the graph definition so IsMemberTargetObjectReference returns true only for IIdentifiable values.
  3. If the member should not be a reference, remove the object-reference flag/attribute so it's serialized inline.
  4. Null-check earlier: the generator already skips null values, so ensure non-null values conform.

Example fix

// before
class MyRef { } // flagged as object reference but not IIdentifiable
// after
class MyRef : IIdentifiable
{
    public Guid Id { get; set; } = Guid.NewGuid();
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is not IIdentifiable) { /* not a valid reference target */ }

Type guard

static bool IsValidReference(object? v) => v is IIdentifiable;

Try / catch

try { generator.Generate(asset); }
catch (InvalidOperationException ex) when (ex.Message.Contains("IsObjectReference")) { /* fix graph definition */ }

Prevention

When it happens

Trigger: A PropertyGraphDefinition's IsMemberTargetObjectReference returns true for a member whose runtime value is not IIdentifiable (custom object-reference types, wrong override of IsObjectReference, or a value type swapped behind an object-reference-typed member).

Common situations: Custom asset types marking non-entity types as object references; a refactor replaced an Entity/IIdentifiable member with a plain class; misconfigured graph definition from a plugin.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sources/assets/Stride.Core.Assets.Quantum/Visitors/ObjectReferencePathGenerator.cs:46

    /// </summary>
    public YamlAssetMetadata<Guid> Result { get; } = new YamlAssetMetadata<Guid>();

    /// <summary>
    /// Gets or sets a method that indicates if a given identifier should be output to the list of object references.
    /// </summary>
    public Func<Guid, bool> ShouldOutputReference { get; set; }

    /// <inheritdoc/>
    protected override void VisitMemberNode(IAssetMemberNode memberNode, int inNonIdentifiableType)
    {
        var value = memberNode.Retrieve();
        if (propertyGraphDefinition.IsMemberTargetObjectReference(memberNode, value))
        {
            if (value == null)
                return;

            if (value is not IIdentifiable identifiable)
                throw new InvalidOperationException("IsObjectReference returned true for an object that is not IIdentifiable");

            var id = identifiable.Id;
            if (ShouldOutputReference?.Invoke(id) ?? true)
                Result.Set(ConvertPath(CurrentPath, inNonIdentifiableType), id);
        }
    }

    /// <inheritdoc/>
    protected override void VisitObjectNode(IAssetObjectNode objectNode, int inNonIdentifiableType)
    {
        if (!objectNode.IsReference)
            return;

        foreach (var index in ((IAssetObjectNodeInternal)objectNode).Indices ?? [])
        {
            if (!propertyGraphDefinition.IsTargetItemObjectReference(objectNode, index, objectNode.Retrieve(index)))
                continue;

View on GitHub (pinned to 96fad776d2)