ppy/osu · error · RulesetLoadException

Creating ruleset instance failed when attempting to create…

Error message

Creating ruleset instance failed when attempting to create playable beatmap.

What it means

Thrown by WorkingBeatmap.GetPlayableBeatmap when ruleset.CreateInstance() returns null. A null return means the IRulesetInfo.InstantiationInfo could not be resolved to a live Ruleset object — typically the ruleset DLL isn't loaded/available in the current AppDomain. This is a RulesetLoadException.

Solutions

  1. Ensure the ruleset assembly is installed and loadable; check the InstantiationInfo string resolves (assembly name + type name present and version-compatible).
  2. Guard upstream: verify ruleset.CreateInstance() is non-null before calling GetPlayableBeatmap, and skip/handle unloaded rulesets.
  3. If the ruleset is genuinely unavailable, present the user with a 'ruleset missing' message rather than letting gameplay/simulation crash.

Example fix

// before
IBeatmap playable = working.GetPlayableBeatmap(rulesetInfo, mods);

// after
var rulesetInstance = rulesetInfo.CreateInstance();
if (rulesetInstance == null)
    throw new RulesetLoadException($"Ruleset '{rulesetInfo.InstantiationInfo}' is not available.");
IBeatmap playable = working.GetPlayableBeatmap(rulesetInfo, mods);
Defensive patterns

Strategy: validation

Validate before calling

var instance = rulesetInfo.CreateInstance();
if (instance == null)
    throw new RulesetLoadException($"Ruleset '{rulesetInfo.InstantiationInfo}' is not available.");
var playable = working.GetPlayableBeatmap(rulesetInfo, mods);

Type guard

static bool IsRulesetAvailable(IRulesetInfo ruleset)
    => ruleset?.CreateInstance() != null;

Try / catch

try { var playable = working.GetPlayableBeatmap(ruleset, mods); }
catch (RulesetLoadException) { /* prompt user to install/enable the ruleset */ }

Prevention

When it happens

Trigger: Calling GetPlayableBeatmap with a RulesetInfo whose InstantiationInfo references a ruleset assembly that is not present (uninstalled ruleset, removed DLL, version mismatch). Also when the ruleset was deserialised from realm with a stale type name.

Common situations: A score or beatmap references a custom/legacy ruleset the user uninstalled; running on a clean install that lacks the ruleset add-on; realm data migrated from another machine whose rulesets weren't copied.

Related errors


AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13). Data as JSON: /api/errors/77d2b5fc398a346f. Report an issue: GitHub.

Appendix: source

Thrown at osu.Game/Beatmaps/WorkingBeatmap.cs:282

            {
                using (var cancellationTokenSource = new CancellationTokenSource(10_000))
                {
                    // don't apply the default timeout when debugger is attached (may be breakpointing / debugging).
                    return GetPlayableBeatmap(ruleset, mods ?? Array.Empty<Mod>(), Debugger.IsAttached ? CancellationToken.None : cancellationTokenSource.Token);
                }
            }
            catch (OperationCanceledException)
            {
                throw new BeatmapLoadTimeoutException(BeatmapInfo);
            }
        }

        public virtual IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods, CancellationToken token)
        {
            var rulesetInstance = ruleset.CreateInstance();

            if (rulesetInstance == null)
                throw new RulesetLoadException("Creating ruleset instance failed when attempting to create playable beatmap.");

            IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance);

            // Check if the beatmap can be converted
            if (Beatmap.HitObjects.Count > 0 && !converter.CanConvert())
                throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter}).");

            // Apply conversion mods
            foreach (var mod in mods.OfType<IApplicableToBeatmapConverter>())
            {
                token.ThrowIfCancellationRequested();
                mod.ApplyToBeatmapConverter(converter);
            }

            // Convert
            IBeatmap converted = converter.Convert(token);

            // Apply conversion mods to the result

View on GitHub (pinned to d9c73e12ad)