dotnet/maui · error · ArgumentNullException

renderer

Error message

renderer

What it means

VisualElementTracker is the iOS-specific component that tracks a VisualElement's property changes and applies them to the native CALayer. Its constructor requires a non-null IVisualElementRenderer because it immediately subscribes to ElementChanged events and reads renderer.Element. Passing null would cause a NullReferenceException on every subsequent operation, so the constructor fails fast with ArgumentNullException.

Source

Thrown at src/Compatibility/Core/src/iOS/VisualElementTracker.cs:48

		VisualElement _element;

		// Track these by hand because the calls down into iOS are too expensive
		bool _isInteractive;
		Rect _lastBounds;
#if !__MOBILE__
		Rect _lastParentBounds;
#endif
		CALayer _layer;
		CGPoint _originalAnchor;
		int _updateCount;

		public VisualElementTracker(IVisualElementRenderer renderer) : this(renderer, true)
		{
		}

		public VisualElementTracker(IVisualElementRenderer renderer, bool trackFrame)
		{
			Renderer = renderer ?? throw new ArgumentNullException("renderer");

			_propertyChangedHandler = HandlePropertyChanged;
			_sizeChangedEventHandler = HandleSizeChanged;
			_batchCommittedHandler = HandleRedrawNeeded;

			TrackFrame = trackFrame;
			renderer.ElementChanged += OnRendererElementChanged;
			SetElement(null, renderer.Element);
		}

		bool TrackFrame { get; set; }

		IVisualElementRenderer Renderer { get; set; }

		public void Dispose()
		{
			Dispose(true);
		}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Ensure the IVisualElementRenderer instance is fully constructed before creating the tracker — pass `this` from within the renderer's own constructor or lifecycle method.
  2. Add a null guard at the call site: `if (renderer != null) _tracker = new VisualElementTracker(renderer);`
  3. If using a factory or DI container, verify the renderer registration returns a non-null instance before passing it to the tracker constructor.

Example fix

// before
_tracker = new VisualElementTracker(someFieldThatMightBeNull);

// after
_tracker = new VisualElementTracker(this); // pass the fully-constructed renderer
Defensive patterns

Strategy: validation

Validate before calling

if (renderer is null)
    throw new InvalidOperationException("Cannot create VisualElementTracker: renderer is not initialized.");
var tracker = new VisualElementTracker(renderer);

Type guard

// Ensure the renderer is non-null and implements IVisualElementRenderer before construction
static bool IsValidRenderer(object? renderer)
    => renderer is IVisualElementRenderer;

Prevention

When it happens

Trigger: Constructing `new VisualElementTracker(null)` or `new VisualElementTracker(null, trackFrame: false)` from a custom renderer whose IVisualElementRenderer field has not yet been assigned. Also occurs when a renderer subclass calls base tracker construction during partial initialization.

Common situations: Custom iOS renderers that instantiate VisualElementTracker in a field initializer or constructor before the renderer itself is fully wired. DI or factory patterns that return null renderers. Refactoring a renderer and forgetting to pass `this`.

Related errors


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