{"record":{"id":"d92fe391cfce1d7b","repo":"dotnet/maui","slug":"element-must-be-a-tabbedpage","errorCode":null,"errorMessage":"Element must be a TabbedPage","messagePattern":"Element must be a TabbedPage","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Compatibility/Core/src/GTK/Renderers/TabbedPageRenderer.cs","lineNumber":33,"sourceCode":"\t\tconst int DefaultIconHeight = 24;\n\n\t\tprotected override void OnElementChanged(VisualElementChangedEventArgs e)\n\t\t{\n\t\t\tbase.OnElementChanged(e);\n\n\t\t\tif (e.OldElement != null)\n\t\t\t{\n\t\t\t\tPage.ChildAdded -= OnPageAdded;\n\t\t\t\tPage.ChildRemoved -= OnPageRemoved;\n\t\t\t\tPage.PagesChanged -= OnPagesChanged;\n\t\t\t}\n\n\t\t\tif (e.NewElement != null)\n\t\t\t{\n\t\t\t\tvar newPage = e.NewElement as TabbedPage;\n\n\t\t\t\tif (newPage == null)\n\t\t\t\t\tthrow new ArgumentException(\"Element must be a TabbedPage\");\n\n\t\t\t\tif (Widget == null)\n\t\t\t\t{\n\t\t\t\t\t// Custom control using a tabbed notebook container.\n\t\t\t\t\tWidget = new NotebookWrapper();\n\t\t\t\t\tControl.Content = Widget;\n\t\t\t\t}\n\n\t\t\t\tInit();\n\t\t\t}\n\t\t}\n\n\t\tvoid Init()\n\t\t{\n\t\t\tOnPagesChanged(Page.Children,\n\t\t\t\t  new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));\n\n\t\t\tPage.ChildAdded += OnPageAdded;","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Compatibility/Core/src/GTK/Renderers/TabbedPageRenderer.cs#L15-L51","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (misregistered)\n[assembly: ExportRenderer(typeof(ContentPage), typeof(TabbedPageRenderer))]\n\n// after\n[assembly: ExportRenderer(typeof(TabbedPage), typeof(TabbedPageRenderer))]","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool IsTabbed(Page p) => p is TabbedPage;","tryCatchPattern":null,"preventionTips":["Register TabbedPageRenderer only against TabbedPage.","Keep ExportRenderer attributes in sync after renames/subclassing.","Use the correct page type for the container you build."],"tags":["gtk","renderer","tabbedpage","type-mismatch","maui","xamarin"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}