stride3d/stride · error · InvalidOperationException

Could not resolve type

Error message

Could not resolve type {typeName}

What it means

After extracting the type name from a cast segment like '(MyType)Member' in an animation property path, UpdateEngine resolves it first via DataSerializerFactory.GetTypeFromAlias and then via AssemblyRegistry.GetType. If both fail, the cast names a type that is not aliased and not registered in any loaded assembly, so compilation cannot proceed.

Solutions

  1. Correct the type name in the path; use the full namespace-qualified name
  2. If ambiguous, use the assembly-qualified name (Type.FullName + ', ' + assembly name)
  3. Ensure the assembly containing the type is loaded and registered with AssemblyRegistry before compiling
  4. Register a type alias via DataSerializerFactory if you want to use a short name

Example fix

// before
var path = '[(MyComponent)Member]'; // unresolved
// after
var path = '[(MyGame.MyNamespace.MyComponent)Member]';
Defensive patterns

Strategy: validation

Validate before calling

static void EnsureCastTypeResolvable(string path) { foreach (var m in System.Text.RegularExpressions.Regex.Matches(path, "\\(([^)]+)\\)")) { var tn = ((System.Text.RegularExpressions.Match)m).Groups[1].Value; if (DataSerializerFactory.GetTypeFromAlias(tn) == null && AssemblyRegistry.GetType(tn) == null) throw new ArgumentException($"Type '{tn}' in path is not registered"); } }

Try / catch

try { var compiler = UpdateEngine.Compile(path, type, ...); } catch (InvalidOperationException ex) when (ex.Message.StartsWith("Could not resolve type")) { // surface the offending type name
    var tn = ex.Message.Replace("Could not resolve type ", ""); throw new ArgumentException($"Unknown type '{tn}' in animation path '{path}'", ex); }

Prevention

When it happens

Trigger: A cast in the animation property path references a type name that is neither a registered alias nor an assembly-qualified name known to AssemblyRegistry, e.g. '[(WrongType)Member]' or using a type from an unloaded assembly.

Common situations: Typos in type names, missing namespace, using short name instead of assembly-qualified name when ambiguous, or referencing types from assemblies not loaded/registered at compile time (e.g. plugin assemblies not referenced).

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Engine/Updater/UpdateEngine.cs:261

                        // Check if it started with a parenthesis (to perform a cast operation)
                        if (animationPath.Name[propertyStart] == PathCastOpen)
                        {
                            // Parse until end of cast operation
                            state.ParseElementEnd = animationPath.Name.IndexOf(PathCastClose, ++propertyStart);
                            if (state.ParseElementEnd == -1)
                                throw new InvalidOperationException("Property path parse error: could not find cast operation ending ')'");

                            var typeName = animationPath.Name.Substring(propertyStart, state.ParseElementEnd - propertyStart);

                            // Include the indexer close
                            state.ParseElementEnd++;

                            // Try to resolve using alias first, then full assembly registry using assembly qualified name
                            var type = DataSerializerFactory.GetTypeFromAlias(typeName) ?? AssemblyRegistry.GetType(typeName);
                            if (type == null)
                            {
                                throw new InvalidOperationException($"Could not resolve type {typeName}");
                            }

                            // Push entry with new type
                            // TODO: Should we actually perform an early castclass and skip if type is incorrect?
                            state.StackPath.Add(new AnimationBuilderStackEntry(type, state.ParseElementStart, state.ParseElementEnd, -1)
                            {
                                ObjectStartOffset = state.NewOffset,
                            });
                        }
                        else
                        {
                            UpdatableMember updatableMember = null;

                            // Parse until end next group (or end)
                            state.ParseElementEnd = animationPath.Name.IndexOfAny(PathGroupDelimiters, state.ParseElementStart + 1);
                            if (state.ParseElementEnd == -1)
                                state.ParseElementEnd = animationPath.Name.Length;

View on GitHub (pinned to 96fad776d2)