dotnet/maui · error · NotSupportedException

Reuse of the Shell Renderer is not supported

Error message

Reuse of the Shell Renderer is not supported

What it means

Thrown by the iOS ShellRenderer.SetElement when SetElement is called on a renderer that already has an Element assigned. ShellRenderer is designed for single-use — once a Shell is bound to a renderer instance, it cannot be rebound. The check is `if (Element != null) throw new NotSupportedException`. This prevents reuse which would cause state corruption in the flyout/navigation infrastructure.

Source

Thrown at src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs:126

					FlyoutRenderer = CreateFlyoutRenderer();
					FlyoutRenderer.AttachFlyout(this, this);
				}
				return _flyoutRenderer;
			}
			set { _flyoutRenderer = value; }
		}

		public event EventHandler<VisualElementChangedEventArgs> ElementChanged;

		public VisualElement Element { get; private set; }
		public UIView NativeView => FlyoutRenderer.View;
		public Shell Shell => (Shell)Element;
		public UIViewController ViewController => FlyoutRenderer.ViewController;

		public void SetElement(VisualElement element)
		{
			if (Element != null)
				throw new NotSupportedException("Reuse of the Shell Renderer is not supported");
			Element = element;
			OnElementSet((Shell)Element);

			ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(null, Element));
			Mapper.UpdateProperties(this, Element);
		}

		[Obsolete]
		public virtual void SetElementSize(Size size)
		{
		}

		public override void ViewDidLayoutSubviews()
		{
			base.ViewDidLayoutSubviews();
			if (_currentShellItemRenderer != null)
				_currentShellItemRenderer.ViewController.View.Frame = View.Bounds;
		}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Ensure the Shell is set as MainPage once and not reassigned to a different Shell instance at runtime — use Shell navigation (GoToAsync) instead of swapping the MainPage.
  2. Update to the latest MAUI version where renderer lifecycle issues may be fixed.
  3. If swapping Shells is necessary, ensure the old Shell's renderer is fully disposed before creating a new one.
  4. Avoid custom handler factories that cache or pool ShellRenderer instances.
  5. File a bug if this occurs under normal single-Shell usage (likely a framework lifecycle regression).

Example fix

// before
MainPage = new AppShell();
// later...
MainPage = new AppShell(); // may reuse renderer on iOS

// after — use Shell navigation, don't swap Shell instances
MainPage = new AppShell();
// navigate within the same Shell:
await Shell.Current.GoToAsync("//login");
Defensive patterns

Strategy: validation

Validate before calling

// Ensure Shell renderer is not reused
if (shellRenderer.Element != null)
    throw new NotSupportedException("ShellRenderer already has an element — create a new instance.");
shellRenderer.SetElement(shell);

Prevention

When it happens

Trigger: At line 126: `if (Element != null) throw`. SetElement is called by the MAUI handler/framework when associating a virtual element with a platform renderer. A second call to SetElement on the same renderer instance triggers this. This is typically caused by: (1) the framework attempting to reuse a disposed/cached renderer; (2) manually calling SetElement on a renderer that was already used; (3) a handler lifecycle bug where the renderer wasn't properly disposed before reuse; (4) Shell being reassigned as MainPage without proper teardown.

Common situations: 1) Setting MainPage to a new Shell instance after a previous Shell was already rendered (if the renderer pool tries to reuse). 2) Custom handler registration that incorrectly pools or reuses ShellRenderer instances. 3) Framework lifecycle bugs in specific MAUI versions where renderer disposal is skipped. 4) Hot reload or live visual tree triggering re-rendering of the Shell.

Related errors


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