{"record":{"id":"318df5a44278e004","repo":"dotnet/maui","slug":"renderer-must-be-a-page-renderer-318df5","errorCode":null,"errorMessage":"renderer must be a Page renderer.","messagePattern":"renderer must be a Page renderer\\.","errorType":"exception","errorClass":"InvalidCastException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs","lineNumber":558,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid UpdateCurrentPage()\n\t\t{\n\t\t\tif (Tabbed is TabbedPage tabbed)\n\t\t\t{\n\t\t\t\tvar count = tabbed.InternalChildren.Count;\n\t\t\t\tvar index = (int)SelectedIndex;\n\t\t\t\ttabbed.CurrentPage = index >= 0 && index < count ? tabbed.GetPageByIndex(index) : null;\n\t\t\t}\n\t\t}\n\n\t\tasync void SetTabBarItem(IPlatformViewHandler renderer)\n\t\t{\n\t\t\tvar page = renderer.VirtualView as Page;\n\t\t\tif (page == null)\n\t\t\t\tthrow new InvalidCastException($\"{nameof(renderer)} must be a {nameof(Page)} renderer.\");\n\n\t\t\tvar icons = await GetIcon(page);\n\t\t\tvar resizedImage = TabbedViewExtensions.AutoResizeTabBarImage(TraitCollection, icons?.Item1);\n\t\t\tvar resizedSelectedImage = TabbedViewExtensions.AutoResizeTabBarImage(TraitCollection, icons?.Item2);\n\t\t\tSetTabBarItem(resizedImage, resizedSelectedImage);\n\t\t\tresizedImage?.Dispose();\n\t\t\tresizedSelectedImage?.Dispose();\n\n\t\t\tvoid SetTabBarItem(UIImage image, UIImage selectedImage)\n\t\t\t{\n\t\t\t\trenderer.ViewController.TabBarItem = new UITabBarItem(page.Title, image, selectedImage)\n\t\t\t\t{\n\t\t\t\t\tTag = Tabbed?.Children.IndexOf(page) ?? -1,\n\t\t\t\t\tAccessibilityIdentifier = page.AutomationId\n\t\t\t\t};\n\t\t\t}\n\n\t\t\ticons?.Item1?.Dispose();","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs#L540-L576","documentation":"Thrown by the iOS TabbedRenderer.SetTabBarItem when the renderer's VirtualView is not a Page. The TabbedRenderer expects each tab's handler to render a Page-derived element (ContentPage, NavigationPage, etc.). If a non-Page visual element was added to the TabbedPage's Children or the handler was misconfigured, the cast `renderer.VirtualView as Page` returns null and InvalidCastException is thrown.","triggerScenarios":"At line 558: `var page = renderer.VirtualView as Page; if (page == null) throw new InvalidCastException`. SetTabBarItem is called to configure each tab's UITabBarItem (title, icon). Triggered when the handler associated with a tab index produces a VirtualView that is not a Page subclass. This can happen when: (1) a non-Page element (e.g., a Layout, ContentView directly) is added to TabbedPage.Children; (2) the handler mapping is misconfigured for a custom element type; (3) a handler returns the wrong VirtualView type.","commonSituations":"1) Adding a ContentView or Layout directly to TabbedPage.Children instead of a ContentPage. 2) Custom handler registration that maps a non-Page type to the TabbedRenderer's tab slots. 3) TabbedPage is a legacy/compatibility API — migration from Xamarin.Forms where Children contained non-Page items that happened to work. 4) Programmatic creation of TabbedPage with incorrect child types.","solutions":["Ensure every child added to TabbedPage.Children is a Page subclass (ContentPage, NavigationPage, etc.).","If using ContentView as tab content, wrap it in a ContentPage first.","Verify handler mappings if using custom element types — only Page-derived elements are valid tab children.","Prefer the modern MAUI TabbedPage alternatives (Shell with tabs, or TabbedPage with proper Page children) over the legacy compatibility path.","Inspect which tab index triggers the error to identify the problematic child."],"exampleFix":"// before\nvar tabbedPage = new TabbedPage();\ntabbedPage.Children.Add(new ContentView { Content = new Label { Text = \"Tab1\" } }); // not a Page!\n\n// after\nvar tabbedPage = new TabbedPage();\ntabbedPage.Children.Add(new ContentPage { Title = \"Tab1\", Content = new Label { Text = \"Tab1\" } });","handlingStrategy":"type-guard","validationCode":"// Verify children are Page types before adding to TabbedPage\nforeach (var child in tabbedPage.Children)\n{\n    if (child is not Page)\n        throw new InvalidCastException($\"TabbedPage child '{child}' must be a Page.\");\n}","typeGuard":"public static bool IsValidTabChild(Element element)\n    => element is Page;","tryCatchPattern":null,"preventionTips":["Only add Page subclasses to TabbedPage.Children.","Wrap ContentView in ContentPage if needed for tab content.","Consider modern alternatives (Shell tabs, TabbedPage with Page children) over legacy Cell/compatibility APIs."],"tags":["maui","ios","tabbedpage","renderer","type-mismatch"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}