dotnet/maui · error · ArgumentException

Element must be a TabbedPage

Error message

Element must be a TabbedPage

What it means

TabbedPageRenderer.SetElement throws ArgumentException if the element is non-null and not a TabbedPage. The renderer is type-specific and uses TabbedPage.Children for its tab collection and binds to TabbedPage-specific properties.

Source

Thrown at src/Compatibility/Core/src/Windows/TabbedPageRenderer.cs:156

			Control.Measure(constraint);
			var result = new Size(Math.Ceiling(Control.DesiredSize.Width), Math.Ceiling(Control.DesiredSize.Height));

			Control.Width = oldWidth;
			Control.Height = oldHeight;

			return new SizeRequest(result);
		}

		UIElement IVisualElementRenderer.GetNativeElement()
		{
			return Control;
		}

		public void SetElement(VisualElement element)
		{
			if (element != null && !(element is TabbedPage))
				throw new ArgumentException("Element must be a TabbedPage", "element");

			TabbedPage oldElement = Element;
			Element = (TabbedPage)element;

			if (oldElement != null)
			{
				oldElement.PropertyChanged -= OnElementPropertyChanged;
				((INotifyCollectionChanged)oldElement.Children).CollectionChanged -= OnPagesChanged;
				Control?.GetDescendantsByName<TextBlock>(TabBarHeaderTextBlockName).ForEach(t => { t.AccessKeyInvoked -= AccessKeyInvokedForTab; });
			}

			if (element != null)
			{
				if (Control == null)
				{
					Control = new FormsPivot
					{
						Style = (Microsoft.UI.Xaml.Style)Microsoft.UI.Xaml.Application.Current.Resources["TabbedPageStyle"],

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Verify the element type is TabbedPage before calling SetElement
  2. Check ExportRenderer attributes for correct type-to-renderer mappings
  3. If building a custom tabbed renderer, inherit from the correct base and ensure the element type constraint

Example fix

// before
var renderer = new TabbedPageRenderer();
renderer.SetElement(new ContentPage()); // throws

// after
var renderer = new TabbedPageRenderer();
renderer.SetElement(new TabbedPage { Children = { page1, page2 } }); // works
Defensive patterns

Strategy: type-guard

Validate before calling

// Before calling SetElement, verify the element type
if (element != null && !(element is TabbedPage))
    throw new ArgumentException($"Expected TabbedPage, got {element.GetType().Name}");
renderer.SetElement(element);

Type guard

static bool IsValidElementForTabbedRenderer(VisualElement element)
{
    return element == null || element is TabbedPage;
}

Prevention

When it happens

Trigger: Explicitly calling SetElement on a TabbedPageRenderer instance with a ContentPage, NavigationPage, or other non-TabbedPage element. Or a misconfigured ExportRenderer attribute mapping TabbedPageRenderer to the wrong element type.

Common situations: Copy-paste error in ExportRenderer registration; custom renderer inheriting from TabbedPageRenderer used for a non-tabbed page; framework internals incorrectly routing element to renderer.

Related errors


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