dotnet/maui · error · ArgumentException
{nameof(element)} must be of type {nameof(Button)}
Error message
{nameof(element)} must be of type {nameof(Button)} What it means
The fast ButtonRenderer's explicit SetElement requires a Button. It null-checks then verifies `element is Button` before casting. The fast-renderer family (Button, Label, Image, Frame) each enforce their concrete type because they are not generic.
Source
Thrown at src/Compatibility/Core/src/Android/FastRenderers/ButtonRenderer.cs:114
var result = _buttonLayoutManager.GetDesiredSize(widthConstraint, heightConstraint);
if (setHint)
Control.Hint = hint;
return result;
}
void IVisualElementRenderer.SetElement(VisualElement element)
{
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
if (!(element is Button))
{
throw new ArgumentException($"{nameof(element)} must be of type {nameof(Button)}");
}
VisualElement oldElement = Button;
Button = (Button)element;
Performance.Start(out string reference);
OnElementChanged(new ElementChangedEventArgs<Button>(oldElement as Button, Button));
SendVisualElementInitialized(element, this);
Performance.Stop(reference);
}
void IVisualElementRenderer.SetLabelFor(int? id)
{
if (_defaultLabelFor == null)
{View on GitHub (pinned to f377ff1c5e)
Solutions
- Ensure ExportRenderer(typeof(Button), typeof(ButtonRenderer)) (or your subclass) is correctly typed.
- Do not pass non-Button elements when reusing or manually driving the renderer.
- If subclassing for a control that extends Button, the check still passes; otherwise pick the right base renderer.
Example fix
// before [assembly: ExportRenderer(typeof(Label), typeof(MyButtonRenderer))] // after [assembly: ExportRenderer(typeof(Button), typeof(MyButtonRenderer))]
Defensive patterns
Strategy: type-guard
Validate before calling
if (element is null) throw new ArgumentNullException(nameof(element));
if (element is not Button) throw new ArgumentException("Expected Button.", nameof(element));
((IVisualElementRenderer)renderer).SetElement(element); Type guard
static bool IsButton(VisualElement e) => e is Button;
Prevention
- Keep ExportRenderer(typeof(Button), ...) attributes accurate.
- Don't reuse fast renderers across control types.
- Validate before any manual renderer attachment.
When it happens
Trigger: SetElement called with a VisualElement that is not a Button — almost always a wrong ExportRenderer registration or a manual renderer call in custom handler code.
Common situations: A custom subclass of ButtonRenderer registered for a non-Button control, or a handler migration where the old fast-renderer attribute points at the wrong control type.
Related errors
- Element must be of type Frame
- Element is not of type " + typeof(Image)
- Element must be of type Label
- {nameof(element)} must be of type {typeof(IndicatorView).Nam
- {nameof(element)} must be of type {typeof(ItemsView).Name}
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/d2ce660c03f8f82f.
Report an issue: GitHub.