ppy/osu · error · InvalidOperationException
Ruleset with ID of {RulesetID} not found locally
Error message
Ruleset with ID of {RulesetID} not found locally What it means
Thrown by SoloScoreInfo.ToScoreInfo when converting an API score into a local ScoreInfo. The method asks the RulesetStore for the score's RulesetID and throws InvalidOperationException if the store has no matching ruleset. The store only contains ruleset assemblies that are installed and enabled on this client.
Source
Thrown at osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs:186
#endregion
/// <summary>
/// Whether this <see cref="ScoreInfo"/> represents a legacy (osu!stable) score.
/// </summary>
[JsonIgnore]
public bool IsLegacyScore => LegacyScoreId != null;
public override string ToString() => $"score_id: {ID} user_id: {UserID}";
/// <summary>
/// Create a <see cref="ScoreInfo"/> from an API score instance.
/// </summary>
/// <param name="rulesets">A ruleset store, used to populate a ruleset instance in the returned score.</param>
/// <param name="beatmap">An optional beatmap, copied into the returned score (for cases where the API does not populate the beatmap).</param>
/// <returns></returns>
public ScoreInfo ToScoreInfo(RulesetStore rulesets, BeatmapInfo? beatmap = null)
{
var ruleset = rulesets.GetRuleset(RulesetID) ?? throw new InvalidOperationException($"Ruleset with ID of {RulesetID} not found locally");
var rulesetInstance = ruleset.CreateInstance();
var mods = Mods.Select(apiMod => apiMod.ToMod(rulesetInstance)).ToArray();
var scoreInfo = ToScoreInfo(mods, beatmap);
scoreInfo.Ruleset = ruleset;
return scoreInfo;
}
/// <summary>
/// Create a <see cref="ScoreInfo"/> from an API score instance.
/// </summary>
/// <param name="mods">The mod instances, resolved from a ruleset.</param>
/// <param name="beatmap">The object to populate the scores' beatmap with.
///<list type="bullet">
/// <item>If this is a <see cref="BeatmapInfo"/> type, then the score will be fully populated with the given object.</item>
View on GitHub (pinned to d9c73e12ad)
Solutions
- Verify all required ruleset assemblies are present and enabled on the client (check RulesetStore.AvailableRulesets).
- Guard before calling: if (!rulesets.AvailableRulesets.Any(r => r.OnlineID == score.RulesetID)) skip or filter the score.
- Wrap the call site in try/catch(InvalidOperationException) and drop the unresolvable score from the list rather than crashing the import/display flow.
Example fix
// before var info = score.ToScoreInfo(rulesets, beatmap); // after var ruleset = rulesets.GetRuleset(score.RulesetID); if (ruleset == null) continue; // unknown ruleset for this client var info = score.ToScoreInfo(rulesets, beatmap);
Defensive patterns
Strategy: validation
Validate before calling
var ruleset = rulesets.GetRuleset(score.RulesetID);
if (ruleset == null)
{
// unknown ruleset for this client; skip this score
continue;
} Type guard
// nullable ruleset check before conversion
RulesetInfo? ResolveRuleset(RulesetStore store, SoloScoreInfo score)
=> store.GetRuleset(score.RulesetID); Try / catch
try { var info = score.ToScoreInfo(rulesets, beatmap); }
catch (InvalidOperationException) { /* filter score: ruleset unavailable locally */ } Prevention
- Never assume the server's ruleset set equals the client's; always resolve via RulesetStore first.
- Filter score lists by AvailableRulesets before bulk conversion.
- Log the unresolved RulesetID to telemetry so missing rulesets are detectable.
When it happens
Trigger: Calling ToScoreInfo(rulesets, beatmap) on a SoloScoreInfo whose RulesetID is not returned by rulesets.GetRuleset(RulesetID). Happens for scores originating from a ruleset the client does not have loaded (e.g. a custom ruleset DLL, or a newer ruleset than the client version).
Common situations: Client is missing the ruleset DLL the server used (version skew after an osu! update, disabled/removed ruleset, or a modded ruleset). Attempting to display/import a score from a ruleset the user uninstalled.
Related errors
- Couldn't create score with unknown ruleset: {RulesetId}
- Ruleset with ID of {Score.RulesetID} not found locally
- Only scores in the osu, taiko, catch, or mania rulesets can
- Ruleset is not available locally.
- Only beatmaps in the osu, taiko, catch, or mania rulesets ca
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/612598a91e09eb12.
Report an issue: GitHub.