dotnet/maui · error · IndexOutOfRangeException

Can't set CarouselView to position {carouselPosition}. Items

Error message

Can't set CarouselView to position {carouselPosition}. ItemsSource has {itemCount} items.

What it means

Thrown by CarouselViewRenderer.UpdateFromPosition when Carousel.Position is greater than or equal to the current ItemsSource count, or is negative. The renderer validates the requested position against the live item count before scrolling the underlying Android CarouselRecyclerView; an out-of-range position would index past the adapter's bounds.

Source

Thrown at src/Compatibility/Core/src/Android/CollectionView/CarouselViewRenderer.cs:534

		{
			if (!_initialized)
			{
				_carouselViewLoopManager.AddPendingScrollTo(new ScrollToRequestEventArgs(Carousel.Position, -1, Microsoft.Maui.Controls.ScrollToPosition.Center, false));
			}

			var itemCount = ItemsViewAdapter?.ItemsSource.Count ?? 0;
			var carouselPosition = Carousel.Position;

			if (itemCount == 0)
			{
				//we are trying to set a position but our Collection doesn't have items still
				_oldPosition = carouselPosition;
				return;
			}


			if (carouselPosition >= itemCount || carouselPosition < 0)
				throw new IndexOutOfRangeException($"Can't set CarouselView to position {carouselPosition}. ItemsSource has {itemCount} items.");

			if (carouselPosition == _gotoPosition)
				_gotoPosition = -1;

			if (_noNeedForScroll)
			{
				_noNeedForScroll = false;
				return;
			}

			var centerPosition = GetCarouselViewCurrentIndex(carouselPosition);
			if (_gotoPosition == -1 && !Carousel.IsDragging && !Carousel.IsScrolling && centerPosition != carouselPosition)
			{
				_gotoPosition = carouselPosition;

				Carousel.ScrollTo(carouselPosition, position: Microsoft.Maui.Controls.ScrollToPosition.Center, animate: Carousel.AnimatePositionChanges);
			}
			SetCurrentItem(carouselPosition);

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Clamp the Position value to the valid range [0, items.Count - 1] before setting it, and reset Position to 0 when ItemsSource is replaced or cleared.
  2. Set ItemsSource before setting Position, and ensure at least one item exists before assigning a non-zero position.
  3. If restoring Position from persisted state, defer the restore until after ItemsSource is populated and validated.

Example fix

// before
carousel.ItemsSource = newItems;
carousel.Position = savedPosition; // throws if savedPosition >= newItems.Count

// after
carousel.ItemsSource = newItems;
carousel.Position = Math.Min(savedPosition, Math.Max(0, newItems.Count - 1));
Defensive patterns

Strategy: validation

Validate before calling

// Clamp Position to a valid range before assigning.
static int ClampPosition(int desired, int itemCount) =>
    itemCount <= 0 ? 0 : Math.Max(0, Math.Min(desired, itemCount - 1));
// Usage:
carousel.Position = ClampPosition(savedPosition, ((IList)carousel.ItemsSource)?.Count ?? 0);

Try / catch

try
{
    carousel.Position = savedPosition;
}
catch (IndexOutOfRangeException ex) when (ex.Message.Contains("CarouselView"))
{
    carousel.Position = 0;
    Log.Warn(nameof(CarouselView), "Saved position out of range; reset to 0.");
}

Prevention

When it happens

Trigger: Binding Carousel.Position to a value that exceeds the number of items. Replacing or clearing ItemsSource while Position retains a stale value. Programmatic position set before items are loaded. Race between ItemsSource collection change and Position property update.

Common situations: Restoring Carousel.Position from persisted state after the items source was reset. Two-way binding Position to a ViewModel property that gets set to an item index that no longer exists. Concurrency between a web request populating items and a position restore.

Related errors


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