stride3d/stride · error · YamlException

Unable to extract asset reference from object

Error message

Unable to extract asset reference from object [{objectContext.Instance}]

What it means

ContentReferenceSerializer.ConvertTo serializes an object back to a YAML string by fetching its attached reference (id + url) through AttachedReferenceManager.GetAttachedReference. When the instance carries no attached reference — meaning it is not a proxy object created with an id/url — it throws YamlException. The library cannot serialize a plain instance as a content reference.

Solutions

  1. Ensure the object being serialized is the proxy created via AttachedReferenceManager.CreateProxyObject (or loaded from an asset), not a manually instantiated instance.
  2. If you replaced a reference with a live instance, restore the proxy (or re-create it with the original guid/url) before saving.
  3. Add a pre-save check: call AttachedReferenceManager.GetAttachedReference(obj) yourself and repair objects that return null.
  4. Keep runtime-resolved instances out of serialized asset graphs; resolve references after deserialization instead.

Example fix

// before: plain instance cannot be serialized as a reference
model = new Model();
asset.Model = model;

// after: keep the attached-reference proxy in the serialized graph
asset.Model = AttachedReferenceManager.CreateProxyObject<Model>(guid, new UFile("mymodel"));
Defensive patterns

Strategy: type-guard

Validate before calling

if (AttachedReferenceManager.GetAttachedReference(instance) is null)
    throw new InvalidOperationException("Instance has no attached reference; create it via AttachedReferenceManager.CreateProxyObject before serializing.");

Type guard

bool IsReferenceProxy(object o) => AttachedReferenceManager.GetAttachedReference(o) != null;

Try / catch

try { return serializer.ConvertTo(ref objectContext); }
catch (YamlException) { /* replace instance with a proxy created from a known guid/url */ }

Prevention

When it happens

Trigger: Saving an asset graph where a field holds a concrete, fully-loaded instance (or a manually constructed object) instead of the AttachedReferenceManager proxy; calling ConvertTo on an object created with Activator/new instead of loaded from a reference.

Common situations: Custom code that replaces a proxy reference with a real instance at runtime and then saves the asset; constructing scene/asset objects programmatically without going through the reference system; serialization after an undo/redo that swapped in live objects.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sources/assets/Stride.Core.Assets/Serializers/ContentReferenceSerializer.cs:35

    {
        return AssetRegistry.IsExactContentType(type);
    }

    public override object ConvertFrom(ref ObjectContext context, Scalar fromScalar)
    {
        if (!AssetReference.TryParse(fromScalar.Value, out var guid, out var location))
        {
            throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to decode asset reference [{0}]. Expecting format GUID:LOCATION".ToFormat(fromScalar.Value));
        }

        var instance = AttachedReferenceManager.CreateProxyObject(context.Descriptor.Type, guid, ReferenceSerializationHelper.RestoreLocation(ref context, location.FullPath));
        return instance;
    }

    public override string ConvertTo(ref ObjectContext objectContext)
    {
        var attachedReference = AttachedReferenceManager.GetAttachedReference(objectContext.Instance)
            ?? throw new YamlException($"Unable to extract asset reference from object [{objectContext.Instance}]");
        return ReferenceSerializationHelper.FormatReference(ref objectContext, attachedReference.Id, attachedReference.Url);
    }
}

View on GitHub (pinned to 96fad776d2)