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
- Verify the page is a TabbedPage: var tabs = new TabbedPage { Children = { ... } }.
- Check the ExportRenderer registration: [assembly: ExportRenderer(typeof(TabbedPage), typeof(TabbedPageRenderer))].
- 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
- Register TabbedPageRenderer only against TabbedPage.
- Keep ExportRenderer attributes in sync after renames/subclassing.
- Use the correct page type for the container you build.
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
- New element must be a CarouselPage
- NavigationPage must have a root Page before being used. Eith
- renderer must be a Page renderer.
- PopToRootAsync is not supported globally on GTK, please use
- PushAsync is not supported globally on GTK, please use a Nav
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/d92fe391cfce1d7b.
Report an issue: GitHub.