ppy/osu · error · InvalidOperationException
Use override with HitType parameter instead
Error message
Use override with HitType parameter instead
What it means
DrumSampleTriggerSource overrides the parameterless Play() method to throw InvalidOperationException because this trigger source must know whether a hit was a Rim (whistle) or Centre (finish) hit to select the correct drum sample. The class provides a Play(HitType) overload instead. Calling the inherited parameterless Play() is a programming error.
Source
Thrown at osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs:59
return;
var baseSample = hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL);
if (strong)
{
PlaySamples(new ISampleInfo[]
{
baseSample,
hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_WHISTLE : HitSampleInfo.HIT_FINISH)
});
}
else
{
PlaySamples(new ISampleInfo[] { baseSample });
}
}
public override void Play() => throw new InvalidOperationException(@"Use override with HitType parameter instead");
protected override void ApplySampleInfo(SkinnableSound hitSound, ISampleInfo[] samples)
{
base.ApplySampleInfo(hitSound, samples);
hitSound.Balance.Value = -0.05 + RNG.NextDouble(0.1);
}
}
public enum SampleBalance
{
Left,
Centre,
Right
}
}
View on GitHub (pinned to d9c73e12ad)
Solutions
- Call the Play(HitType) overload: drumSampleTriggerSource.Play(hitType).
- If working through a base HitSampleTriggerSource reference, cast to DrumSampleTriggerSource or resolve the HitType before calling.
- If polymorphic dispatch is unavoidable, check the runtime type and branch to the correct overload.
Example fix
// before — base reference, parameterless Play
HitSampleTriggerSource source = GetTriggerSource();
source.Play(); // throws if source is DrumSampleTriggerSource
// after — use the HitType overload
if (source is DrumSampleTriggerSource drumSource)
drumSource.Play(hitType);
else
source.Play(); Defensive patterns
Strategy: type-guard
Validate before calling
// Check the concrete type before calling Play
if (triggerSource is DrumSampleTriggerSource drumSource)
drumSource.Play(hitType);
else
triggerSource.Play(); Type guard
static bool RequiresHitTypeParameter(HitSampleTriggerSource source)
=> source is DrumSampleTriggerSource; Prevention
- When working with DrumSampleTriggerSource, always use the Play(HitType) overload.
- If dispatching through a base reference, check the runtime type and branch to the correct overload.
- Consider adding a unit test that verifies Play(HitType) works and Play() throws for this type.
When it happens
Trigger: Calling drumSampleTriggerSource.Play() without a HitType argument. This commonly happens when generic code holds a reference to the base class (HitSampleTriggerSource or Drawable) and dispatches through the parameterless Play() without knowing the concrete type requires a HitType.
Common situations: Polymorphic code that calls Play() on a base HitSampleTriggerSource reference; refactoring that accidentally routes through the base method; code that was written for a non-Taiko trigger source and reused without adaptation.
Related errors
- Adjust via RepeatCount instead
- Unknown hit object type.
- Invalid component type: {component}
- Invalid result type: {result}
- A {nameof(PoolableSkinnableSample)} cannot be applied multip
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/65474741d8b85a68.
Report an issue: GitHub.