ppy/osu · error
Legacy replay cannot be converted for the ruleset: {currentR
Error message
Legacy replay cannot be converted for the ruleset: {currentRuleset.Description} What it means
Thrown in convertFrame when currentRuleset.CreateConvertibleReplayFrame() returns null, meaning the active ruleset does not implement legacy-to-modern replay frame conversion. The decoder was asked to translate legacy replay frames into the ruleset's native frame type but the ruleset offers no converter.
Source
Thrown at osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs:358
foreach (var legacyFrame in legacyFrames)
{
// never allow backwards time traversal in relation to the current frame.
// this handles frames with negative delta.
// this doesn't match stable 100% as stable will do something similar to adding an interpolated "intermediate frame"
// at the point wherein time flow changes from backwards to forwards, but it'll do for now.
if (currentFrame != null && legacyFrame.Time < currentFrame.Time)
continue;
replay.Frames.Add(currentFrame = convertFrame(legacyFrame, currentFrame));
}
}
private ReplayFrame convertFrame(LegacyReplayFrame currentFrame, ReplayFrame lastFrame)
{
var convertible = currentRuleset.CreateConvertibleReplayFrame();
if (convertible == null)
throw new InvalidOperationException($"Legacy replay cannot be converted for the ruleset: {currentRuleset.Description}");
convertible.FromLegacy(currentFrame, currentBeatmap, lastFrame);
var frame = (ReplayFrame)convertible;
frame.Time = currentFrame.Time;
return frame;
}
/// <summary>
/// Retrieves the <see cref="Ruleset"/> for a specific id.
/// </summary>
/// <param name="rulesetId">The id.</param>
/// <returns>The <see cref="Ruleset"/>.</returns>
protected abstract Ruleset GetRuleset(int rulesetId);
/// <summary>
/// Retrieves the <see cref="WorkingBeatmap"/> corresponding to an MD5 hash.
View on GitHub (pinned to d9c73e12ad)
Solutions
- Confirm the ruleset is one of the legacy-capable rulesets (osu, taiko, catch, mania) before attempting legacy replay conversion.
- If authoring a custom ruleset, implement CreateConvertibleReplayFrame() to return a type deriving from ConvertibleReplayFrame.
- Guard the decode path: skip conversion (or report 'unsupported') when currentRuleset.CreateConvertibleReplayFrame() == null instead of forcing it.
- Check that the score's RulesetID matches the ruleset the replay was recorded under.
Example fix
// before
var convertible = currentRuleset.CreateConvertibleReplayFrame();
if (convertible == null)
throw new InvalidOperationException($"Legacy replay cannot be converted for the ruleset: {currentRuleset.Description}");
// after (caller-side guard)
if (currentRuleset.CreateConvertibleReplayFrame() == null)
{
Logger.Log($"Ruleset '{currentRuleset.Description}' does not support legacy replay conversion; skipping.");
return;
} Defensive patterns
Strategy: validation
Validate before calling
if (currentRuleset.CreateConvertibleReplayFrame() == null)
{
Logger.Log($"No legacy converter for {currentRuleset.Description}; skipping conversion.");
return;
} Type guard
static bool RulesetSupportsLegacyConversion(Ruleset r)
=> r.CreateConvertibleReplayFrame() != null; Try / catch
try { convertFrame(legacyFrame, lastFrame); }
catch (InvalidOperationException) { /* ruleset cannot convert legacy replay */ } Prevention
- Check CreateConvertibleReplayFrame() != null before converting legacy replays.
- Implement the converter in custom rulesets that must read stable replays.
- Match the score's RulesetID to the replay's origin ruleset.
When it happens
Trigger: A legacy replay (osu!stable format) is being decoded/converted for a ruleset whose CreateConvertibleReplayFrame() returns null. Common with non-legacy or custom rulesets that never defined a LegacyReplayFrame converter.
Common situations: Importing a stable replay for a ruleset that does not support legacy replays; switching a score's target ruleset at runtime to one without a converter; using a custom ruleset that forgot to override CreateConvertibleReplayFrame.
Related errors
- input .lzma is too short
- Can't Read 1
- Unknown hit object type.
- 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/d25363c8e1b75124.
Report an issue: GitHub.