{"record":{"id":"8d20a293db317907","repo":"ppy/osu","slug":"ruleset-could-not-be-loaded-type-lookup-failure","errorCode":null,"errorMessage":"Ruleset could not be loaded (Type lookup failure)","messagePattern":"Ruleset could not be loaded \\(Type lookup failure\\)","errorType":"exception","errorClass":"RulesetLoadException","httpStatus":null,"severity":"error","filePath":"osu.Game/Rulesets/RulesetInfo.cs","lineNumber":105,"sourceCode":"        public RulesetInfo Clone() => new RulesetInfo\r\n        {\r\n            OnlineID = OnlineID,\r\n            Name = Name,\r\n            ShortName = ShortName,\r\n            InstantiationInfo = InstantiationInfo,\r\n            Available = Available,\r\n            LastAppliedDifficultyVersion = LastAppliedDifficultyVersion,\r\n        };\r\n\r\n        public Ruleset CreateInstance()\r\n        {\r\n            if (!Available)\r\n                throw new RulesetLoadException(@\"Ruleset not available\");\r\n\r\n            var type = Type.GetType(InstantiationInfo);\r\n\r\n            if (type == null)\r\n                throw new RulesetLoadException(@\"Type lookup failure\");\r\n\r\n            var ruleset = Activator.CreateInstance(type) as Ruleset;\r\n\r\n            if (ruleset == null)\r\n                throw new RulesetLoadException(@\"Instantiation failure\");\r\n\r\n            // overwrite the pre-populated RulesetInfo with a potentially database attached copy.\r\n            // TODO: figure if we still want/need this after switching to realm.\r\n            // ruleset.RulesetInfo = this;\r\n\r\n            return ruleset;\r\n        }\r\n    }\r\n}\r\n","sourceCodeStart":87,"sourceCodeEnd":120,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/Rulesets/RulesetInfo.cs#L87-L120","documentation":"Thrown as RulesetLoadException by RulesetInfo.CreateInstance when Type.GetType(InstantiationInfo) returns null. The stored assembly-qualified type name could not be resolved to a loaded type, meaning the ruleset assembly is not loaded or the type was renamed/moved.","triggerScenarios":"InstantiationInfo (an assembly-qualified name persisted in the database) no longer resolves: the ruleset DLL is missing, the type's namespace/name changed, or the assembly failed to load.","commonSituations":"Ruleset DLL deleted or renamed; ruleset refactor moving the Ruleset class; version skew where stored InstantiationInfo points at an older/newer assembly identity than what is loaded.","solutions":["Install/restore the ruleset assembly referenced by InstantiationInfo.","If the type moved, re-scan rulesets so InstantiationInfo is updated to the current type name.","Guard on Available / catch RulesetLoadException and treat the ruleset as missing."],"exampleFix":"// before\nvar instance = rulesetInfo.CreateInstance();\n\n// after\nif (!rulesetInfo.Available || Type.GetType(rulesetInfo.InstantiationInfo) == null)\n    return null;\nvar instance = rulesetInfo.CreateInstance();","handlingStrategy":"validation","validationCode":"if (!rulesetInfo.Available || Type.GetType(rulesetInfo.InstantiationInfo) == null)\n    return null;\nvar instance = rulesetInfo.CreateInstance();","typeGuard":"bool TypeResolves(string instantiationInfo) => Type.GetType(instantiationInfo) != null;","tryCatchPattern":"try { var instance = rulesetInfo.CreateInstance(); }\ncatch (RulesetLoadException) { /* type not found: skip or re-scan */ }","preventionTips":["Keep InstantiationInfo in sync with the loaded assembly identity.","Re-scan rulesets after install/remove/rename so stored type names refresh.","Guard Type.GetType before instantiating in performance-sensitive loops."],"tags":["ruleset","load","reflection","type-resolution","ruleset-load-exception"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}