{"record":{"id":"2255674fdc0c5117","repo":"elsa-workflows/elsa-core","slug":"type-typename-not-found","errorCode":null,"errorMessage":"Type {typeName} not found.","messagePattern":"Type (.+?) not found\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Common/Helpers/TypeHelper.cs","lineNumber":11,"sourceCode":"using System.Reflection;\n\nnamespace Elsa.Common.Helpers;\n\npublic static class TypeHelper\n{\n    public static Type GetLatestType(string typeName)\n    {\n        var type = Type.GetType(typeName);\n        var deprecatedByTypeAttribute = type?.GetCustomAttribute<ForwardedTypeAttribute>();\n        return deprecatedByTypeAttribute?.NewType ?? type ?? throw new InvalidOperationException($\"Type {typeName} not found.\");\n    }\n}","sourceCodeStart":1,"sourceCodeEnd":13,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Common/Helpers/TypeHelper.cs#L1-L13","documentation":"TypeHelper.GetLatestType resolves a type by assembly-qualified name and follows ForwardedTypeAttribute to the current replacement type. If Type.GetType returns null (name not found) it throws this InvalidOperationException with the original type name.","triggerScenarios":"Calling GetLatestType with a type name that is misspelled, not assembly-qualified, belongs to an assembly not loaded, or was renamed/moved in a newer package version.","commonSituations":"Stored workflow definitions persisting old type names after a package upgrade; types in assemblies not yet loaded (Type.GetType only searches the executing assembly and mscorlib for partial names); typos in configuration.","solutions":["Use the assembly-qualified name (Namespace.Type, AssemblyName) so Type.GetType can find it.","Ensure the assembly containing the type is loaded, or use a type resolver that scans AppDomain/dependency context.","Add [ForwardedType] forwarding or update persisted definitions to the new type name after renames.","Verify the exact stored name with typeof(X).AssemblyQualifiedName and compare."],"exampleFix":"// before\nTypeHelper.GetLatestType(\"Elsa.MyApp.OldActivity\");\n// after\nTypeHelper.GetLatestType(\"Elsa.MyApp.NewActivity, Elsa.MyApp\");","handlingStrategy":"validation","validationCode":"var type = Type.GetType(typeName, throwOnError: false);\nif (type == null)\n    throw new InvalidOperationException($\"Type '{typeName}' is not resolvable; use an assembly-qualified name and ensure the assembly is loaded.\");","typeGuard":"bool IsResolvableTypeName(string? typeName) => !string.IsNullOrWhiteSpace(typeName) && Type.GetType(typeName, throwOnError: false) != null;","tryCatchPattern":"try { var type = TypeHelper.GetLatestType(typeName); }\ncatch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Type \") && ex.Message.EndsWith(\" not found.\")) { logger.LogError(ex, \"Unknown or renamed type: {TypeName}\", typeName); }","preventionTips":["Persist typeof(X).AssemblyQualifiedName, never short names","After package upgrades, scan stored definitions for stale type names","Add ForwardedTypeAttribute when renaming types to keep old definitions loading"],"tags":["reflection","type-resolution","dotnet"],"backgroundTag":"class-not-found","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}