ppy/osu · error · InvalidOperationException

Unknown hit object type.

Error message

Unknown hit object type.

What it means

TaikoAutoGenerator generates replay frames by switching on the type of each hit object (Hit, DrumRoll, and Swell are handled). The default case throws InvalidOperationException for any unhandled type, indicating a new or unexpected hit object subclass was encountered during auto-replay generation.

Source

Thrown at osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs:115

                        if (hit.Type == HitType.Centre)
                        {
                            actions = hit.IsStrong
                                ? new[] { TaikoAction.LeftCentre, TaikoAction.RightCentre }
                                : new[] { hitButton ? TaikoAction.LeftCentre : TaikoAction.RightCentre };
                        }
                        else
                        {
                            actions = hit.IsStrong
                                ? new[] { TaikoAction.LeftRim, TaikoAction.RightRim }
                                : new[] { hitButton ? TaikoAction.LeftRim : TaikoAction.RightRim };
                        }

                        Frames.Add(new TaikoReplayFrame(h.StartTime, actions));
                        break;
                    }

                    default:
                        throw new InvalidOperationException("Unknown hit object type.");
                }

                var nextHitObject = GetNextObject(i); // Get the next object that requires pressing the same button

                bool canDelayKeyUp = nextHitObject == null || nextHitObject.StartTime > endTime + KEY_UP_DELAY;
                double calculatedDelay = canDelayKeyUp ? KEY_UP_DELAY : (nextHitObject.AsNonNull().StartTime - endTime) * 0.9;
                Frames.Add(new TaikoReplayFrame(endTime + calculatedDelay));

                hitButton = !hitButton;
            }
        }
    }
}

View on GitHub (pinned to d9c73e12ad)

Solutions

  1. Add a case for the new hit object type in the switch that generates appropriate replay frames.
  2. If the unhandled type is unexpected, audit the beatmap parsing to determine why an unknown type was created.

Example fix

// before
case Hit h:
    ...
case DrumRoll d:
    ...
case Swell s:
    ...
default:
    throw new InvalidOperationException("Unknown hit object type.");

// after — add the missing case
case DrumRoll d:
    ...
case Swell s:
    ...
case SwapHit sw:
    // generate replay frames for the new type
    Frames.Add(new TaikoReplayFrame(sw.StartTime, TaikoAction.LeftCentre, TaikoAction.RightCentre));
    break;
Defensive patterns

Strategy: type-guard

Validate before calling

// Check the hit object type before adding to the beatmap or generating replays
static bool IsSupportedTaikoHitObject(HitObject ho)
    => ho is Hit or DrumRoll or Swell;

Type guard

// Type guard for Taiko hit object types
static bool IsSupportedTaikoHitObject(HitObject ho)
    => ho is Hit or DrumRoll or Swell;

Prevention

When it happens

Trigger: A Taiko hit object of a type not covered by the switch (not Hit, not DrumRoll (IHasDuration), not Swell) is present in the beatmap when the auto generator processes it.

Common situations: Extending the Taiko ruleset with a new hit object type without updating the auto-replay generator; ruleset forking; deserialization of a beatmap with custom hit object types that the generator doesn't recognize.

Related errors


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