{"record":{"id":"f27a21ac83959e70","repo":"stride3d/stride","slug":"cannot-serialize-an-object-of-type-assetpart-gettype-name-as","errorCode":null,"errorMessage":"Cannot serialize an object of type {assetPart.GetType().Name} as an asset part reference: the type does not implement {typeof(IIdentifiable).Name}","messagePattern":"Cannot serialize an object of type (.+?) as an asset part reference: the type does not implement (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/Serializers/IdentifiableAssetPartReference.cs","lineNumber":35,"sourceCode":"    /// Gets or sets the identifier of the asset part represented by this reference.\n    /// </summary>\n    public Guid Id { get; set; }\n\n    /// <inheritdoc/>\n    [DataMemberIgnore]\n    public Type InstanceType { get; set; }\n\n    /// <inheritdoc/>\n    public override string ToString()\n    {\n        return $\"{{AssetPartReference: {Id}}}\";\n    }\n\n    /// <inheritdoc/>\n    public void FillFromPart(object assetPart)\n    {\n        if (assetPart is not IIdentifiable identifiable)\n            throw new InvalidOperationException($\"Cannot serialize an object of type {assetPart.GetType().Name} as an asset part reference: the type does not implement {typeof(IIdentifiable).Name}\");\n\n        Id = identifiable?.Id ?? Guid.Empty;\n    }\n\n    /// <inheritdoc/>\n    public object? GenerateProxyPart(Type partType)\n    {\n        if (!typeof(IIdentifiable).IsAssignableFrom(partType))\n            throw new InvalidOperationException($\"Cannot serialize an object of type {partType.Name} as an asset part reference: the type does not implement {typeof(IIdentifiable).Name}\");\n\n        if (Id == Guid.Empty)\n            return null;\n\n        var assetPart = (IIdentifiable)Activator.CreateInstance(partType)!;\n        assetPart.Id = Id;\n        return assetPart;\n    }\n}","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/Serializers/IdentifiableAssetPartReference.cs#L17-L53","documentation":"IdentifiableAssetPartReference.FillFromPart builds a lightweight reference (id only) from an actual asset part. The part must implement IIdentifiable so its Id can be captured; when it does not, the method throws InvalidOperationException because a reference cannot be formed without an identifier. This is a contract check protecting the serialization pipeline.","triggerScenarios":"Calling FillFromPart with an object whose runtime type does not implement IIdentifiable — e.g. passing a plain model/effect object or a custom asset part that forgot to implement IIdentifiable while still being registered as an asset part.","commonSituations":"Custom asset part types added to an asset without implementing IIdentifiable; API changes between library versions where a part type lost its IIdentifiable implementation; wiring up wrong objects (a wrapper instead of the part) in custom editor tooling.","solutions":["Make the asset part class implement IIdentifiable (inheriting from the framework's Identifiable base) so it exposes an Id.","Pass the correct part object — the IIdentifiable asset part rather than a plain wrapper — to FillFromPart.","Guard the call with 'assetPart is IIdentifiable' and skip or log parts that cannot be referenced.","If a library type regressed, wrap or adapt it in your own IIdentifiable implementation carrying the id."],"exampleFix":"// before\nclass MyPart { public Guid Id; ... } // not IIdentifiable\nreference.FillFromPart(new MyPart());\n\n// after\nclass MyPart : Identifiable { ... }\nreference.FillFromPart(new MyPart());","handlingStrategy":"type-guard","validationCode":"if (assetPart is not IIdentifiable)\n    throw new ArgumentException(\"Asset part must implement IIdentifiable\", nameof(assetPart));","typeGuard":"bool IsReferencablePart(object part) => part is IIdentifiable;","tryCatchPattern":"try { reference.FillFromPart(part); }\ncatch (InvalidOperationException) { log.Warn($\"Skipping non-identifiable part {part.GetType().Name}\"); }","preventionTips":["Derive all custom asset parts from the Identifiable base class","Assert parts implement IIdentifiable at registration time","Pass the part itself, not a wrapper, to FillFromPart","Add unit tests exercising the reference round-trip for custom parts"],"tags":["serialization","asset-part","identifiable","type-mismatch"],"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"}