dotnet/maui · error · ArgumentException
element must be of type RadioButton
Error message
element must be of type RadioButton
What it means
Thrown by RadioButtonRenderer.SetElement when the VisualElement passed to the renderer is not a RadioButton. The AppCompat RadioButton renderer is bound exclusively to the RadioButton control type; receiving any other element indicates a misregistered handler or incorrect element assignment.
Source
Thrown at src/Compatibility/Core/src/Android/AppCompat/RadioButtonRenderer.cs:78
((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, hasFocus);
}
SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint)
{
Measure(widthConstraint, heightConstraint);
return new SizeRequest(new Size(MeasuredWidth, MeasuredHeight));
}
void IVisualElementRenderer.SetElement(VisualElement element)
{
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
if (!(element is RadioButton))
{
throw new ArgumentException($"{nameof(element)} must be of type {nameof(RadioButton)}");
}
RadioButton oldElement = Element;
Element = (RadioButton)element;
Performance.Start(out string reference);
if (oldElement != null)
{
oldElement.PropertyChanged -= OnElementPropertyChanged;
}
element.PropertyChanged += OnElementPropertyChanged;
if (_tracker == null)
{
// Can't set up the tracker in the constructor because it access the Element (for now)
SetTracker(new VisualElementTracker(this));View on GitHub (pinned to f377ff1c5e)
Solutions
- Verify the ExportRenderer/handler registration maps RadioButton (and only RadioButton) to RadioButtonRenderer.
- Confirm the element passed is a RadioButton, not a CheckBox, Switch, or custom control.
- For custom radio-button-like controls, subclass RadioButton or register a dedicated renderer for your type.
Example fix
// before [assembly: ExportRenderer(typeof(CheckBox), typeof(RadioButtonRenderer))] // after [assembly: ExportRenderer(typeof(RadioButton), typeof(RadioButtonRenderer))]
Defensive patterns
Strategy: type-guard
Type guard
static bool IsRadioButtonElement(VisualElement element) => element is RadioButton;
Prevention
- Audit ExportRenderer attributes; RadioButtonRenderer must map only to RadioButton.
- Distinguish RadioButton from CheckBox and Switch in registrations.
- Add a renderer-resolution unit test asserting the correct element type for each registered renderer.
When it happens
Trigger: An ExportRenderer attribute maps a non-RadioButton type to RadioButtonRenderer, or the renderer is manually invoked with the wrong element. Also surfaces when a custom control masquerading as a radio button is registered against the wrong renderer.
Common situations: Confusing RadioButton with CheckBox or a custom toggle control in ExportRenderer attributes. Version upgrades where RadioButton's namespace changed. Reusing RadioButtonRenderer for a custom selection control without subclassing RadioButton.
Related errors
- Element is not of type CheckBox
- Element is not of type ImageButton
- {nameof(element)} must be of type {typeof(IndicatorView).Nam
- {nameof(element)} must be of type {typeof(ItemsView).Name}
- {nameof(element)} must be of type {nameof(Button)}
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/94f070a6ce2434af.
Report an issue: GitHub.