stride3d/stride · error · YamlException
Unable to find class from tag
Error message
Unable to find class from tag [{0}] What it means
PropertyKeyYamlSerializer.ConvertFrom parses a scalar of the form 'ClassName.PropertyName' to resolve a public static field (a PropertyKey) at deserialization time. It first resolves the class from the YAML tag via TypeFromTag; if no type is registered for the '!ClassName' tag, this YamlException is thrown.
Solutions
- Ensure the assembly containing the class is loaded and registered with the asset/serializer type system before deserializing
- Fix the class name in the YAML scalar or tag to match the current class name
- Restore the renamed/moved class or update all assets referencing the old tag
- Re-save the asset in the Stride editor so tags and class names are regenerated
Example fix
// before MyProperty: !OldNamespaceOldClass.MyPropertyKey value // after MyProperty: !MyNamespaceMyClass.MyPropertyKey value
Defensive patterns
Strategy: try-catch
Try / catch
try { value = ConvertFrom(ref context, scalar); } catch (YamlException ex) when (ex.Message.StartsWith("Unable to find class")) { log.Error($"Missing type for tag {scalar.Value}: {ex.Message}"); throw; } Prevention
- Ensure all assemblies declaring PropertyKeys are loaded before deserialization
- Avoid renaming classes containing PropertyKeys without migrating assets
- Keep tag aliases in sync with the type registry
When it happens
Trigger: Deserializing a YAML asset that references a PropertyKey whose class tag ('!' + className) is not found by the SerializerContext's tag registry — typically because the containing assembly is not loaded/scanned or the class was renamed/moved.
Common situations: Renaming or deleting a class containing PropertyKeys after assets referenced them; the plugin/assembly declaring the class not loaded at deserialization time; YAML tag aliases out of sync with the type registry after refactors.
Related errors
- Unable to find property
- Multiple identifiable objects with the same id
- Unable to decode asset part reference
- Unable to deserialize reference
- Unable to decode url reference
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/98eb2bcfa51550ad.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/Serializers/PropertyKeyYamlSerializer.cs:41
}
for (Type? t = type; t != null; t = t.BaseType)
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(PropertyKey<>))
return true;
return false;
}
public override object? ConvertFrom(ref ObjectContext objectContext, Scalar fromScalar)
{
var lastDot = fromScalar.Value.LastIndexOf('.');
if (lastDot == -1)
return null;
var className = fromScalar.Value[..lastDot];
var containingClass = objectContext.SerializerContext.TypeFromTag("!" + className, out var typeAliased)
?? throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to find class from tag [{0}]".ToFormat(className)); // Readd initial '!'
var propertyName = fromScalar.Value[(lastDot + 1)..];
var propertyField = containingClass.GetField(propertyName, BindingFlags.Public | BindingFlags.Static)
?? throw new YamlException(fromScalar.Start, fromScalar.End, "Unable to find property [{0}] in class [{1}]".ToFormat(propertyName, containingClass.Name));
return propertyField.GetValue(null);
}
protected override void WriteScalar(ref ObjectContext objectContext, ScalarEventInfo scalar)
{
// TODO: if ParameterKey is written to an object, It will not serialized a tag
scalar.Tag = null;
scalar.IsPlainImplicit = true;
base.WriteScalar(ref objectContext, scalar);
}
public override string ConvertTo(ref ObjectContext objectContext)
{
var propertyKey = (PropertyKey)objectContext.Instance;View on GitHub (pinned to 96fad776d2)