dotnet/maui · error · ArgumentNullException
ContentLoader
Error message
ContentLoader
What it means
FormsContentControl.OnContentLoaderChanged throws ArgumentNullException("ContentLoader") when the WPF DependencyProperty is set to null. LightContentControl_SizeChanged immediately dereferences ContentLoader, so null would NRE on the next resize unless rejected here.
Source
Thrown at src/Compatibility/Core/src/WPF/Controls/FormsContentControl.cs:44
set { SetValue(ContentLoaderProperty, value); }
}
public FormsContentControl()
{
this.DefaultStyleKey = typeof(FormsContentControl);
this.SizeChanged += LightContentControl_SizeChanged;
}
private void LightContentControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
this.ContentLoader.OnSizeContentChanged(this, Source);
}
private static void OnContentLoaderChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null)
{
throw new ArgumentNullException("ContentLoader");
}
}
private static void OnSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
((FormsContentControl)o).OnSourceChanged(e.OldValue, e.NewValue);
}
private void OnSourceChanged(object oldValue, object newValue)
{
if (newValue != null && newValue.Equals(oldValue))
return;
var localTokenSource = new CancellationTokenSource();
this.tokenSource = localTokenSource;
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
var task = this.ContentLoader.LoadContentAsync(this, oldValue, newValue, this.tokenSource.Token);View on GitHub (pinned to f377ff1c5e)
Solutions
- Assign a concrete IContentLoader (FormsContentLoader or DefaultContentLoader) before the control measures its content.
- Use FallbackValue on the binding so a null source resolves to a default loader.
- Never null ContentLoader during teardown; dispose the underlying page instead.
- Verify any {StaticResource}/{DynamicResource} reference resolves at runtime.
Example fix
// before control.ContentLoader = null; // after control.ContentLoader = new FormsContentLoader();
Defensive patterns
Strategy: validation
Validate before calling
control.ContentLoader = control.ContentLoader ?? new FormsContentLoader();
Type guard
static bool HasValidLoader(FormsContentControl c) => c.ContentLoader != null;
Try / catch
try { control.ContentLoader = loader; }
catch (ArgumentNullException) { control.ContentLoader = new FormsContentLoader(); } Prevention
- Provide a default ContentLoader in the control's XAML template.
- Use FallbackValue in ContentLoader bindings.
- Audit cleanup paths to ensure they never null the property.
When it happens
Trigger: Setting FormsContentControl.ContentLoader to null in XAML or code; a binding to ContentLoader that resolves to null; clearing the property without assigning a replacement loader.
Common situations: Resource lookup failure for the ContentLoader; DataContext unset so the binding evaluates to null; explicit teardown nulling the loader; loader swap that assigns null before constructing the new loader.
Related errors
- ContentLoader
- UIThreadRequired
- UIThreadRequired
- Unable to find the required services. Please add all the req
- RootComponent requires a value for its Selector property, bu
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/89fe487131ad2c8e.
Report an issue: GitHub.