dotnet/maui · error · ArgumentException

New element must be a CarouselPage

Error message

New element must be a CarouselPage

What it means

CarouselPageRenderer.OnElementChanged casts e.NewElement to CarouselPage; if the element is any other Page type the cast yields null and it throws ArgumentException. The renderer is registered for CarouselPage specifically, so a non-CarouselPage element reaching it means a registration mismatch or a wrong element assignment. The same pattern is used across renderers (e.g. TabbedPageRenderer) to fail fast on type violations.

Source

Thrown at src/Compatibility/Core/src/GTK/Renderers/CarouselPageRenderer.cs:65

			base.Dispose(disposing);
		}

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

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

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

				if (newPage == null)
					throw new ArgumentException("New element must be a CarouselPage");

				if (Widget == null)
				{
					Widget = new Carousel();
					Widget.Animated = true;

					var eventBox = new GtkFormsContainer();
					eventBox.Add(Widget);
					Control.Content = eventBox;
				}

				Init();
			}
		}

		protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			base.OnElementPropertyChanged(sender, e);

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Ensure the page being rendered is actually a CarouselPage (new CarouselPage { Children = ... }).
  2. Check any [assembly: ExportRenderer(typeof(...), typeof(CarouselPageRenderer))] attribute maps CarouselPage, not another page type.
  3. If subclassing CarouselPage, confirm the subclass is still assignable to CarouselPage and that the renderer is registered for the base type.

Example fix

// before (wrong registration)
[assembly: ExportRenderer(typeof(ContentPage), typeof(CarouselPageRenderer))]

// after
[assembly: ExportRenderer(typeof(CarouselPage), typeof(CarouselPageRenderer))]
Defensive patterns

Strategy: type-guard

Type guard

static bool IsCarousel(Page p) => p is CarouselPage;
// before assigning/using:
if (!IsCarousel(myPage)) throw new InvalidOperationException("CarouselPage required");

Prevention

When it happens

Trigger: A renderer is explicitly bound to CarouselPage (via ExportRenderer or the default registration) but receives a ContentPage/TabbedPage/other Page. Can also occur if Element is manually swapped to an incompatible type, or a custom ExportRenderer attribute misroutes the type.

Common situations: Wrong ExportRenderer registration (registering CarouselPageRenderer for ContentPage). Copy-paste of renderer registration across page types. Manually assigning an incompatible element to a renderer during custom rendering.

Related errors


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