stride3d/stride · error · ArgumentException
Class type is expected.
Error message
Class type is expected.
What it means
PropertyContainer.AddAccessorProperty registers a PropertyKey as an accessor property for a type, and the registry is keyed by Type with the assumption it maps to class instances. Passing a struct, enum, interface, or other non-class Type throws ArgumentException because accessor semantics only apply to class types.
Solutions
- Pass the concrete class type that owns the property.
- Constrain generic helper methods with `where T : class`.
- If the type is a struct by design, do not use accessor-property registration for it.
Example fix
// before PropertyContainer.AddAccessorProperty(typeof(MyPoint), PositionKey); // struct // after PropertyContainer.AddAccessorProperty(typeof(MyEntity), PositionKey); // class
Defensive patterns
Strategy: type-guard
Validate before calling
if (!type.GetTypeInfo().IsClass)
throw new InvalidOperationException("AddAccessorProperty requires a class type"); Type guard
static bool IsClass(Type t) => t.GetTypeInfo().IsClass;
Try / catch
try { PropertyContainer.AddAccessorProperty(type, key); }
catch (ArgumentException ex) when (ex.Message == "Class type is expected.")
{
// caller passed a struct/interface; skip or resolve the concrete class
} Prevention
- Constrain generics to `where T : class` before calling AddAccessorProperty.
- Resolve interfaces to their concrete implementation class before registering.
- Only register accessor properties for class-based entities/components.
When it happens
Trigger: Calling PropertyContainer.AddAccessorProperty(typeof(SomeStruct) or an interface, somePropertyKey) where the type's TypeInfo.IsClass is false.
Common situations: Registering accessor properties for value-type models or interfaces; generic helper code that forwards typeof(T) where T is unconstrained and instantiated with a struct.
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
- Given PropertyKey doesn't have accessor metadata.
- Unexpected arguments
- This tool requires a build path.
- Type [ ] must be assignable to Asset or be a Package
- Type [ ] must be assignable to Asset
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0ca3b339b4527e24.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core/PropertyContainer.cs:527
PropertyUpdated?.Invoke(ref this, propertyKey, tagValue, previousValue);
propertyKey.PropertyUpdateCallback?.Invoke(ref this, propertyKey, tagValue, previousValue);
}
}
else
{
if (tryToAdd)
properties.Add(propertyKey, valueToSet);
else
properties[propertyKey] = valueToSet;
}
propertyKey.ObjectInvalidationMetadata?.Invalidate(Owner, propertyKey, oldValue);
}
public static void AddAccessorProperty(Type type, PropertyKey propertyKey)
{
if (!type.GetTypeInfo().IsClass)
throw new ArgumentException("Class type is expected.", nameof(type));
if (propertyKey.AccessorMetadata == null)
throw new ArgumentException("Given PropertyKey doesn't have accessor metadata.", nameof(propertyKey));
if (!AccessorProperties.TryGetValue(type, out var typeAccessorProperties))
AccessorProperties.Add(type, typeAccessorProperties = []);
typeAccessorProperties.Add(propertyKey);
}
internal void RaisePropertyContainerUpdated(PropertyKey propertyKey, object newValue, object oldValue)
{
PropertyUpdated?.Invoke(ref this, propertyKey, newValue, oldValue);
}
private object? GetNonRecursive(PropertyKey propertyKey)
{
// Get bound value, if any.View on GitHub (pinned to 96fad776d2)