{"record":{"id":"b2af9343e5cac2db","repo":"stride3d/stride","slug":"invalid-fulltype-name-fullyqualifiedtypename-expecting-an","errorCode":null,"errorMessage":"Invalid fulltype name [${fullyQualifiedTypeName}], expecting an assembly name","messagePattern":"Invalid fulltype name \\[(.+?)\\], expecting an assembly name","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core/Reflection/AssemblyRegistry.cs","lineNumber":81,"sourceCode":"    }\n\n    /// <summary>\n    /// Gets a type by its typename already loaded in the assembly registry.\n    /// </summary>\n    /// <param name=\"fullyQualifiedTypeName\">The typename</param>\n    /// <param name=\"throwOnError\"></param>\n    /// <returns>The type instance or null if not found.</returns>\n    /// <seealso cref=\"Type.GetType(string,bool)\"/>\n    /// <seealso cref=\"Assembly.GetType(string,bool)\"/>\n    [UnconditionalSuppressMessage(\"Trimming\", \"IL2026\", Justification = \"Name lookup over registered assemblies; callers root the concrete types.\")]\n    [UnconditionalSuppressMessage(\"Trimming\", \"IL2057\", Justification = \"Name lookup over registered assemblies; callers root the concrete types.\")]\n    public static Type? GetType(string fullyQualifiedTypeName, bool throwOnError = true)\n    {\n        ArgumentNullException.ThrowIfNull(fullyQualifiedTypeName);\n        var assemblyIndex = fullyQualifiedTypeName.IndexOf(',');\n        if (assemblyIndex < 0)\n        {\n            throw new ArgumentException($\"Invalid fulltype name [{fullyQualifiedTypeName}], expecting an assembly name\", nameof(fullyQualifiedTypeName));\n        }\n        var typeName = fullyQualifiedTypeName[..assemblyIndex];\n        var assemblyName = new AssemblyName(fullyQualifiedTypeName[(assemblyIndex + 1)..]);\n        lock (Lock)\n        {\n            if (AssemblyNameToAssembly.TryGetValue(assemblyName.Name!, out var assembly))\n            {\n                return assembly.GetType(typeName, throwOnError, false);\n            }\n        }\n\n        // Fallback to default lookup\n        return Type.GetType(fullyQualifiedTypeName, throwOnError, false);\n    }\n\n    /// <summary>\n    /// Finds registered assemblies that are associated with the specified categories.\n    /// </summary>","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core/Reflection/AssemblyRegistry.cs#L63-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Append the assembly name: pass 'TypeName, AssemblyShortName' (no full assembly version needed)","When you already have a Type object, use typeof/GetType directly instead of round-tripping through its FullName","If the name comes from legacy data, migrate stored strings to include the assembly qualifier","For unqualified input, split and re-qualify it yourself with a default assembly before calling","Catch ArgumentException and surface a clear message telling users the required 'Type,Assembly' format"],"exampleFix":"// before\nvar type = AssemblyRegistry.GetType(\"Stride.Engine.EntityComponent\");\n// after\nvar type = AssemblyRegistry.GetType(\"Stride.Engine.EntityComponent, Stride.Engine\");","handlingStrategy":"validation","validationCode":"if (name == null || !name.Contains(','))\n    throw new ArgumentException($\"Type name '{name}' must be in 'TypeName, AssemblyName' format\");","typeGuard":"bool IsAssemblyQualified(string? name) =>\n    !string.IsNullOrWhiteSpace(name) && name.IndexOf(',') > 0;","tryCatchPattern":"try\n{\n    var type = AssemblyRegistry.GetType(name);\n}\ncatch (ArgumentException ex)\n{\n    logger.Error(ex, \"Type name must include assembly qualifier: {Name}\", name);\n}","preventionTips":["Always store 'TypeName, AssemblyShortName' in configs/assets, never bare FullName","Don't feed typeof(T).FullName into AssemblyRegistry.GetType; use typeof(T) directly","Normalize/validate type-name strings at configuration load time","Migrate legacy serialized type names once, centrally"],"tags":["reflection","type-resolution","argument-format","stride"],"backgroundTag":"invalid-argument-format","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}