dotnet/maui · error · ArgumentException

Element must be of type Frame.

Error message

Element must be of type Frame.

What it means

MaterialFrameRenderer on iOS (Catalyst/iOS) renders a Frame using an MDCCard scheme from Material Components. Its SetElement method throws ArgumentException if the incoming element cannot be cast to Frame. The card-scheme styling, corner radius, and elevation logic are all Frame-specific.

Source

Thrown at src/Compatibility/Material/src/iOS/MaterialFrameRenderer.cs:77

			ApplyThemeIfNeeded();
		}

		public void SetElement(VisualElement element)
		{
			_cardScheme?.Dispose();
			_cardScheme = CreateCardScheme();

			var oldElement = Element;

			if (oldElement != null)
			{
				oldElement.PropertyChanged -= OnElementPropertyChanged;
			}

			if (element is null)
				Element = null;
			else
				Element = element as Frame ?? throw new ArgumentException("Element must be of type Frame.");

			if (Element != null)
			{
				if (_packager == null)
				{
					_defaultCardScheme = CreateCardScheme();

					_packager = new VisualElementPackager(this);
					_packager.Load();

					_tracker = new VisualElementTracker(this);

					_events = new EventTracker(this);
					_events.LoadEvents(this);
				}

				Element.PropertyChanged += OnElementPropertyChanged;

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Verify the iOS ExportRenderer maps Frame to MaterialFrameRenderer.
  2. Ensure the element passed to SetElement is a Frame instance or derives from Frame.
  3. In embedding scenarios, create the correct renderer type for the element you are embedding.
  4. Audit for stale registrations after migration from Frame to Border.

Example fix

// before
renderer.SetElement(myContentView); // not a Frame

// after
renderer.SetElement(myFrame); // myFrame is of type Frame
Defensive patterns

Strategy: type-guard

Validate before calling

if (element is not Frame frame)
    throw new InvalidOperationException($"Expected Frame, got {element?.GetType().Name}");
iOSRenderer.SetElement(frame);

Type guard

static bool IsFrame(VisualElement? element) => element is Frame;

Prevention

When it happens

Trigger: Calling SetElement on MaterialFrameRenderer with a non-Frame element. Occurs when the handler registrar dispatches the wrong element type, or when manually invoking SetElement with an incompatible control during custom embedding scenarios.

Common situations: Custom embedding code that reuses a MaterialFrameRenderer for a different element. MAUI migration where Frame was replaced by Border but the iOS renderer mapping was not updated. Conflicting ExportRenderer declarations across assemblies.

Related errors


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