stride3d/stride · error · ArgumentException

Invalid fulltype name

Error message

Invalid fulltype name [${fullyQualifiedTypeName}], expecting an assembly name

What it means

AssemblyRegistry.GetType resolves a type from a fully-qualified name of the form 'TypeName, AssemblyName'. The comma-separated assembly-qualifier is mandatory because the registry is indexed by assembly; without a comma the method cannot determine which assembly to search, so it throws ArgumentException.

Solutions

  1. Append the assembly name: pass 'TypeName, AssemblyShortName' (no full assembly version needed)
  2. When you already have a Type object, use typeof/GetType directly instead of round-tripping through its FullName
  3. If the name comes from legacy data, migrate stored strings to include the assembly qualifier
  4. For unqualified input, split and re-qualify it yourself with a default assembly before calling
  5. Catch ArgumentException and surface a clear message telling users the required 'Type,Assembly' format

Example fix

// before
var type = AssemblyRegistry.GetType("Stride.Engine.EntityComponent");
// after
var type = AssemblyRegistry.GetType("Stride.Engine.EntityComponent, Stride.Engine");
Defensive patterns

Strategy: validation

Validate before calling

if (name == null || !name.Contains(','))
    throw new ArgumentException($"Type name '{name}' must be in 'TypeName, AssemblyName' format");

Type guard

bool IsAssemblyQualified(string? name) =>
    !string.IsNullOrWhiteSpace(name) && name.IndexOf(',') > 0;

Try / catch

try
{
    var type = AssemblyRegistry.GetType(name);
}
catch (ArgumentException ex)
{
    logger.Error(ex, "Type name must include assembly qualifier: {Name}", name);
}

Prevention

When it happens

Trigger: Calling AssemblyRegistry.GetType with a type name lacking the ',AssemblyName' suffix, e.g. GetType("MyNamespace.MyClass") instead of GetType("MyNamespace.MyClass, MyAssembly"); passing a typeof().FullName string (which omits the assembly) directly into the API; deserializing older data that stored unqualified type names.

Common situations: Building dynamic instantiation/plugin loading from config strings where only the CLR FullName was recorded; migrating serialized assets from formats that dropped the assembly qualifier; hand-writing type names in YAML/asset files; reflection helpers concatenating namespace+type without the assembly.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at sources/core/Stride.Core/Reflection/AssemblyRegistry.cs:81

    }

    /// <summary>
    /// Gets a type by its typename already loaded in the assembly registry.
    /// </summary>
    /// <param name="fullyQualifiedTypeName">The typename</param>
    /// <param name="throwOnError"></param>
    /// <returns>The type instance or null if not found.</returns>
    /// <seealso cref="Type.GetType(string,bool)"/>
    /// <seealso cref="Assembly.GetType(string,bool)"/>
    [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Name lookup over registered assemblies; callers root the concrete types.")]
    [UnconditionalSuppressMessage("Trimming", "IL2057", Justification = "Name lookup over registered assemblies; callers root the concrete types.")]
    public static Type? GetType(string fullyQualifiedTypeName, bool throwOnError = true)
    {
        ArgumentNullException.ThrowIfNull(fullyQualifiedTypeName);
        var assemblyIndex = fullyQualifiedTypeName.IndexOf(',');
        if (assemblyIndex < 0)
        {
            throw new ArgumentException($"Invalid fulltype name [{fullyQualifiedTypeName}], expecting an assembly name", nameof(fullyQualifiedTypeName));
        }
        var typeName = fullyQualifiedTypeName[..assemblyIndex];
        var assemblyName = new AssemblyName(fullyQualifiedTypeName[(assemblyIndex + 1)..]);
        lock (Lock)
        {
            if (AssemblyNameToAssembly.TryGetValue(assemblyName.Name!, out var assembly))
            {
                return assembly.GetType(typeName, throwOnError, false);
            }
        }

        // Fallback to default lookup
        return Type.GetType(fullyQualifiedTypeName, throwOnError, false);
    }

    /// <summary>
    /// Finds registered assemblies that are associated with the specified categories.
    /// </summary>

View on GitHub (pinned to 96fad776d2)