dotnet/maui · error · ArgumentNullException

newElement

Error message

newElement

What it means

UpdateNewElement(VisualElement newElement) re-syncs the native subview tree when the parent's element is replaced. It immediately reads newElement's LogicalChildren (line 58) and compares them against _oldElement's children, so a null newElement would NPE during that diff. The guard rejects null before the diff.

Source

Thrown at src/Compatibility/Core/src/iOS/RendererPool.cs:52

		{
			if (view == null)
				throw new ArgumentNullException("view");

			var rendererType = Controls.Internals.Registrar.Registered.GetHandlerTypeForObject(view) ?? typeof(ViewRenderer);

			Stack<IVisualElementRenderer> renderers;
			if (!_freeRenderers.TryGetValue(rendererType, out renderers) || renderers.Count == 0)
				return null;

			var renderer = renderers.Pop();
			renderer.SetElement(view);
			return renderer;
		}

		public void UpdateNewElement(VisualElement newElement)
		{
			if (newElement == null)
				throw new ArgumentNullException("newElement");

			var sameChildrenTypes = true;

			var oldChildren = ((IElementController)_oldElement).LogicalChildren;
			var oldNativeChildren = _parent.NativeView.Subviews;
			var newChildren = ((IElementController)newElement).LogicalChildren;

			if (oldChildren.Count == newChildren.Count && oldNativeChildren.Length >= oldChildren.Count)
			{
				for (var i = 0; i < oldChildren.Count; i++)
				{
					var oldChildType = (oldNativeChildren[i] as IVisualElementRenderer)?.Element?.GetType();
					if (oldChildType != newChildren[i].GetType())
					{
						sameChildrenTypes = false;
						break;
					}
				}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Guard UpdateNewElement calls: only invoke it when e.NewElement is non-null (skip on detach).
  2. In OnElementChanged, return early if args.NewElement == null rather than pooling.
  3. Migrate off the obsolete RendererPool to handler-based recycling.

Example fix

// before
_pool.UpdateNewElement(e.NewElement);

// after
if (e.NewElement != null)
    _pool.UpdateNewElement(e.NewElement);
Defensive patterns

Strategy: validation

Validate before calling

if (e.NewElement == null) return;
_pool.UpdateNewElement(e.NewElement);

Prevention

When it happens

Trigger: Calling pool.UpdateNewElement(null), which happens when the renderer's OnElementChanged receives a newElement that is null (element detached) and forwards it to the pool unconditionally.

Common situations: Element swap during disposal; a custom renderer forwarding e.NewElement to UpdateNewElement without checking the ElementChanged event semantics.

Related errors


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