dotnet/maui · error · ArgumentException

Element must be a TabbedPage

Error message

Element must be a TabbedPage

What it means

TabbedPageRenderer.OnElementChanged casts e.NewElement to TabbedPage; any other Page type yields null and throws ArgumentException. The renderer is registered for TabbedPage, so receiving a different type indicates a misrouted registration or an incompatible element assignment. This is the standard fail-fast type guard used across the GTK renderers.

Source

Thrown at src/Compatibility/Core/src/GTK/Renderers/TabbedPageRenderer.cs:33

		const int DefaultIconHeight = 24;

		protected override void OnElementChanged(VisualElementChangedEventArgs e)
		{
			base.OnElementChanged(e);

			if (e.OldElement != null)
			{
				Page.ChildAdded -= OnPageAdded;
				Page.ChildRemoved -= OnPageRemoved;
				Page.PagesChanged -= OnPagesChanged;
			}

			if (e.NewElement != null)
			{
				var newPage = e.NewElement as TabbedPage;

				if (newPage == null)
					throw new ArgumentException("Element must be a TabbedPage");

				if (Widget == null)
				{
					// Custom control using a tabbed notebook container.
					Widget = new NotebookWrapper();
					Control.Content = Widget;
				}

				Init();
			}
		}

		void Init()
		{
			OnPagesChanged(Page.Children,
				  new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));

			Page.ChildAdded += OnPageAdded;

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Verify the page is a TabbedPage: var tabs = new TabbedPage { Children = { ... } }.
  2. Check the ExportRenderer registration: [assembly: ExportRenderer(typeof(TabbedPage), typeof(TabbedPageRenderer))].
  3. If subclassing TabbedPage, register the renderer against TabbedPage (base type) or the exact subclass consistently.

Example fix

// before (misregistered)
[assembly: ExportRenderer(typeof(ContentPage), typeof(TabbedPageRenderer))]

// after
[assembly: ExportRenderer(typeof(TabbedPage), typeof(TabbedPageRenderer))]
Defensive patterns

Strategy: type-guard

Type guard

static bool IsTabbed(Page p) => p is TabbedPage;

Prevention

When it happens

Trigger: A renderer resolves to TabbedPageRenderer for a non-TabbedPage element (wrong ExportRenderer mapping), or a TabbedPageRenderer instance has its Element set to an incompatible Page type manually.

Common situations: Copy-pasted ExportRenderer attribute pointing TabbedPageRenderer at the wrong page type. Subclassing a page without updating renderer registration. Custom rendering code that swaps elements across renderer instances.

Related errors


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