ppy/osu · error · RulesetLoadException
Ruleset could not be loaded (Instantiation failure)
Error message
Ruleset could not be loaded (Instantiation failure)
What it means
Thrown by RulesetInfo.CreateInstance when Activator.CreateInstance(type) succeeds but the resulting object cannot be cast to Ruleset. This means the type referenced by InstantiationInfo exists in the loaded assemblies but does not inherit from osu.Game.Rulesets.Ruleset. It is distinct from the 'Type lookup failure' sibling (type == null) and 'Ruleset not available' (Available flag off).
Source
Thrown at osu.Game/Rulesets/RulesetInfo.cs:110
InstantiationInfo = InstantiationInfo,
Available = Available,
LastAppliedDifficultyVersion = LastAppliedDifficultyVersion,
};
public Ruleset CreateInstance()
{
if (!Available)
throw new RulesetLoadException(@"Ruleset not available");
var type = Type.GetType(InstantiationInfo);
if (type == null)
throw new RulesetLoadException(@"Type lookup failure");
var ruleset = Activator.CreateInstance(type) as Ruleset;
if (ruleset == null)
throw new RulesetLoadException(@"Instantiation failure");
// overwrite the pre-populated RulesetInfo with a potentially database attached copy.
// TODO: figure if we still want/need this after switching to realm.
// ruleset.RulesetInfo = this;
return ruleset;
}
}
}
View on GitHub (pinned to d9c73e12ad)
Solutions
- Inspect the value of InstantiationInfo for the offending ruleset and confirm the named type is a non-abstract Ruleset subclass in a loaded assembly.
- If the ruleset type was renamed/moved, update InstantiationInfo (or delete and re-register the RulesetInfo row) to point at the correct fully-qualified type name.
- If the ruleset assembly is missing or incompatible, remove/disable the ruleset entry rather than letting instantiation proceed.
- Wrap CreateInstance() calls in ruleset-loading UI with a RulesetLoadException handler to surface a user-facing message instead of crashing.
Example fix
// before
var type = Type.GetType(InstantiationInfo);
var ruleset = Activator.CreateInstance(type) as Ruleset;
// after (diagnostic)
var type = Type.GetInstance(InstantiationInfo);
if (type != null && !typeof(Ruleset).IsAssignableFrom(type))
throw new RulesetLoadException($@"Type {type.FullName} is not a Ruleset subclass.");
var ruleset = Activator.CreateInstance(type) as Ruleset; Defensive patterns
Strategy: validation
Validate before calling
var type = Type.GetType(instantiationInfo);
if (type == null || !typeof(Ruleset).IsAssignableFrom(type) || type.IsAbstract)
return; // skip; do not call CreateInstance()
var ruleset = (Ruleset)Activator.CreateInstance(type); Type guard
static bool IsInstantiableRuleset(string instantiationInfo)
=> Type.GetType(instantiationInfo) is Type t
&& typeof(Ruleset).IsAssignableFrom(t)
&& !t.IsAbstract; Try / catch
try { return rulesetInfo.CreateInstance(); }
catch (RulesetLoadException ex) { Logger.Log($"Ruleset load failed: {ex.Message}"); return null; } Prevention
- Keep InstantiationInfo in sync with the actual Ruleset type name after renames.
- Validate InstantiationInfo against loaded assemblies before invoking CreateInstance.
- Treat a failed ruleset load as a disabled ruleset, not a crash.
When it happens
Trigger: InstantiationInfo points to a Type that is not a Ruleset subclass (e.g. a class named similarly, a RulesetInfo subclass, or a stub). Occurs when a ruleset assembly is present but the declared InstantiationInfo string names a non-Ruleset type.
Common situations: Migrating a custom ruleset that renamed its primary Ruleset class but left the database/InstantiationInfo pointing at the old name; corrupted RulesetInfo rows after an incompatible ruleset update; a ruleset DLL that only partially matches the expected API.
Related errors
- Ruleset could not be loaded (Type lookup failure)
- Ruleset is not available locally.
- Only beatmaps in the osu, taiko, catch, or mania rulesets ca
- Creating ruleset instance failed when attempting to create p
- Beatmap can not be converted for the ruleset (ruleset: {rule
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/fe21b798dee4f382.
Report an issue: GitHub.