{"record":{"id":"e437d5539b8d8fa5","repo":"stride3d/stride","slug":"isobjectreference-returned-true-for-an-object-that-is-not","errorCode":null,"errorMessage":"IsObjectReference returned true for an object that is not IIdentifiable","messagePattern":"IsObjectReference returned true for an object that is not IIdentifiable","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets.Quantum/Visitors/ObjectReferencePathGenerator.cs","lineNumber":46,"sourceCode":"    /// </summary>\n    public YamlAssetMetadata<Guid> Result { get; } = new YamlAssetMetadata<Guid>();\n\n    /// <summary>\n    /// Gets or sets a method that indicates if a given identifier should be output to the list of object references.\n    /// </summary>\n    public Func<Guid, bool> ShouldOutputReference { get; set; }\n\n    /// <inheritdoc/>\n    protected override void VisitMemberNode(IAssetMemberNode memberNode, int inNonIdentifiableType)\n    {\n        var value = memberNode.Retrieve();\n        if (propertyGraphDefinition.IsMemberTargetObjectReference(memberNode, value))\n        {\n            if (value == null)\n                return;\n\n            if (value is not IIdentifiable identifiable)\n                throw new InvalidOperationException(\"IsObjectReference returned true for an object that is not IIdentifiable\");\n\n            var id = identifiable.Id;\n            if (ShouldOutputReference?.Invoke(id) ?? true)\n                Result.Set(ConvertPath(CurrentPath, inNonIdentifiableType), id);\n        }\n    }\n\n    /// <inheritdoc/>\n    protected override void VisitObjectNode(IAssetObjectNode objectNode, int inNonIdentifiableType)\n    {\n        if (!objectNode.IsReference)\n            return;\n\n        foreach (var index in ((IAssetObjectNodeInternal)objectNode).Indices ?? [])\n        {\n            if (!propertyGraphDefinition.IsTargetItemObjectReference(objectNode, index, objectNode.Retrieve(index)))\n                continue;\n","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets.Quantum/Visitors/ObjectReferencePathGenerator.cs#L28-L64","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Make the member's value type implement IIdentifiable (or derive from IdentifiableEntity/Entity) so it has an Id.","Fix the graph definition so IsMemberTargetObjectReference returns true only for IIdentifiable values.","If the member should not be a reference, remove the object-reference flag/attribute so it's serialized inline.","Null-check earlier: the generator already skips null values, so ensure non-null values conform."],"exampleFix":"// before\nclass MyRef { } // flagged as object reference but not IIdentifiable\n// after\nclass MyRef : IIdentifiable\n{\n    public Guid Id { get; set; } = Guid.NewGuid();\n}","handlingStrategy":"type-guard","validationCode":"if (value is not IIdentifiable) { /* not a valid reference target */ }","typeGuard":"static bool IsValidReference(object? v) => v is IIdentifiable;","tryCatchPattern":"try { generator.Generate(asset); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"IsObjectReference\")) { /* fix graph definition */ }","preventionTips":["Only flag IIdentifiable types as object references","Keep graph definitions in sync with member types","Test reference generation over all asset types"],"tags":["stride","quantum","references","invariant"],"backgroundTag":"type-mismatch","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}