ppy/osu · error · ArgumentException
Provided argument must be of type {nameof(Drawable)}.
Error message
Provided argument must be of type {nameof(Drawable)}. What it means
Thrown by SkinnableContainer.Add when the ISerialisableDrawable passed in is not a Drawable. The container's backing content requires a Drawable to insert into the draw tree; pure interface implementations without Drawable are rejected.
Source
Thrown at osu.Game/Skinning/SkinnableContainer.cs:88
LoadComponentAsync(content, wrapper =>
{
AddInternal(wrapper);
components.AddRange(wrapper.Children.OfType<ISerialisableDrawable>());
ComponentsLoaded = true;
OnComponentsLoaded?.Invoke(this);
}, (cancellationSource = new CancellationTokenSource()).Token);
}
/// <inheritdoc cref="ISerialisableDrawableContainer"/>
/// <exception cref="NotSupportedException">Thrown when attempting to add an element to a target which is not supported by the current skin.</exception>
/// <exception cref="ArgumentException">Thrown if the provided instance is not a <see cref="Drawable"/>.</exception>
public void Add(ISerialisableDrawable component)
{
if (content == null)
throw new NotSupportedException("Attempting to add a new component to a target container which is not supported by the current skin.");
if (!(component is Drawable drawable))
throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(component));
content.Add(drawable);
components.Add(component);
}
/// <inheritdoc cref="ISerialisableDrawableContainer"/>
/// <exception cref="NotSupportedException">Thrown when attempting to add an element to a target which is not supported by the current skin.</exception>
/// <exception cref="ArgumentException">Thrown if the provided instance is not a <see cref="Drawable"/>.</exception>
public void Remove(ISerialisableDrawable component, bool disposeImmediately)
{
if (content == null)
throw new NotSupportedException("Attempting to remove a new component from a target container which is not supported by the current skin.");
if (!(component is Drawable drawable))
throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(component));
content.Remove(drawable, disposeImmediately);
components.Remove(component);
View on GitHub (pinned to d9c73e12ad)
Solutions
- Ensure the component class inherits from Drawable (and implements ISerialisableDrawable).
- Pass the underlying Drawable instance rather than a non-drawable wrapper.
- Type-check before Add: if (component is Drawable) container.Add(component); else log error.
Example fix
// before
class MyComponent : ISerialisableDrawable { ... } // not a Drawable
container.Add(new MyComponent());
// after
class MyComponent : Drawable, ISerialisableDrawable { ... }
container.Add(new MyComponent()); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(component is Drawable))
throw new ArgumentException("Component must be a Drawable."); Type guard
static bool IsDrawableComponent(ISerialisableDrawable c) => c is Drawable;
Try / catch
try { container.Add(component); }
catch (ArgumentException) { /* not a Drawable */ } Prevention
- Ensure custom components derive from Drawable.
- Pass the underlying Drawable, not a wrapper.
- Type-check before Add.
When it happens
Trigger: Passing an ISerialisableDrawable implementation that does not derive from Drawable (the framework's Drawable base class) to Add().
Common situations: Custom serialisable component implemented as a plain class implementing the interface but not extending Drawable; passing a wrapper/DTO instead of the real component.
Related errors
- Attempting to add a new component to a target container whic
- Attempting to remove a new component from a target container
- Invalid component type: {component}
- Attempting to use this setter will not work correctly. Use s
- A {nameof(PoolableSkinnableSample)} cannot be applied multip
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/d218d7f7b11066b9.
Report an issue: GitHub.