dotnet/maui · error · ArgumentException
Element must be of type Frame.
Error message
Element must be of type Frame.
What it means
MaterialFrameRenderer renders Material Design Frame elements on Android. SetElement casts the VisualElement to Frame and throws ArgumentException on mismatch. The renderer applies Material card-scheme corner radius and elevation logic specific to Frame, so an incompatible element cannot be processed.
Source
Thrown at src/Compatibility/Material/src/Android/MaterialFrameRenderer.cs:283
if (_defaultBackgroundDrawable == null)
_defaultBackgroundDrawable = Background;
_backgroundGradientDrawable = new GradientDrawable();
_backgroundGradientDrawable.SetShape(ShapeType.Rectangle);
_backgroundGradientDrawable.SetCornerRadius(Radius);
_backgroundGradientDrawable.UpdateBackground(bgBrush, Height, Width);
Background = _backgroundGradientDrawable;
}
}
// IVisualElementRenderer
VisualElement IVisualElementRenderer.Element => Element;
VisualElementTracker IVisualElementRenderer.Tracker => _visualElementTracker;
AView IVisualElementRenderer.View => this;
void IVisualElementRenderer.SetElement(VisualElement element) =>
Element = (element as Frame) ?? throw new ArgumentException("Element must be of type Frame.");
void IVisualElementRenderer.UpdateLayout() =>
_visualElementTracker?.UpdateLayout();
SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint)
{
var context = Context;
return new SizeRequest(new Size(context.ToPixels(20), context.ToPixels(20)));
}
void IVisualElementRenderer.SetLabelFor(int? id)
{
if (_defaultLabelFor == null)
_defaultLabelFor = ViewCompat.GetLabelFor(this);
ViewCompat.SetLabelFor(this, (int)(id ?? _defaultLabelFor));
}
// IEffectControlProviderView on GitHub (pinned to f377ff1c5e)
Solutions
- Confirm the ExportRenderer attribute maps Frame to MaterialFrameRenderer.
- If migrating from Frame to Border/ContentView, update both the element type and the renderer accordingly.
- Ensure no custom element type without a Frame base is registered against this renderer.
- Check for conflicting registrations across multiple assemblies.
Example fix
// before [assembly: ExportRenderer(typeof(ContentView), typeof(MaterialFrameRenderer))] // after [assembly: ExportRenderer(typeof(Frame), typeof(MaterialFrameRenderer))]
Defensive patterns
Strategy: type-guard
Validate before calling
if (element is not Frame)
throw new InvalidOperationException($"Expected Frame, got {element?.GetType().Name}");
renderer.SetElement(element); Type guard
static bool IsFrame(VisualElement? element) => element is Frame;
Prevention
- Confirm ExportRenderer maps Frame to MaterialFrameRenderer.
- Update registrations when migrating from Frame to Border/ContentView.
- Audit for conflicting Frame registrations across assemblies.
When it happens
Trigger: The handler dispatch sends a non-Frame element to MaterialFrameRenderer. Happens with incorrect ExportRenderer registrations or when migrating a custom ContentView to be rendered by the Frame renderer.
Common situations: Confusing Frame with ContentView or Border in renderer registrations. MAUI migration where Frame was replaced by Border but the renderer mapping was not updated. Custom layouts accidentally mapped to the Frame renderer.
Related errors
- {element?.GetType().FullName} is not compatible. element mus
- Element must be of type Button.
- Element must be of type ProgressBar.
- Element must be of type Slider.
- Element must be of type Frame.
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/c1c15ca47520b895.
Report an issue: GitHub.