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
- Ensure the IVisualElementRenderer instance is fully constructed before creating the tracker — pass `this` from within the renderer's own constructor or lifecycle method.
- Add a null guard at the call site: `if (renderer != null) _tracker = new VisualElementTracker(renderer);`
- 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
- Always pass `this` (the fully-constructed renderer) when creating a VisualElementTracker inside a renderer class.
- Avoid field initializers that create trackers before the renderer is constructed.
- Use nullable reference types to catch null renderer assignments at compile time.
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.