dotnet/maui · error · ArgumentException

must be of type

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.

Solutions

  1. Ensure ExportRenderer(typeof(Button), typeof(ButtonRenderer)) (or your subclass) is correctly typed.
  2. Do not pass non-Button elements when reusing or manually driving the renderer.
  3. 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

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


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/d2ce660c03f8f82f. Report an issue: GitHub.

Appendix: 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)