dotnet/maui · error · InvalidOperationException

Cannot apply relative binding when the target object is null

Error message

Cannot apply relative binding when the target object is null.

What it means

InvalidOperationException from Binding.Apply when Source is a RelativeBindingSource, RelativeSourceTargetOverride is null, and the target bindObj itself is null. The ternary picks the null-target branch of the message because bindObj is null, so the converter cannot even report a type. Relative bindings require a concrete Element anchor, and a null anchor is unrecoverable.

Source

Thrown at src/Controls/src/Core/Binding.cs:165

			object src = _source;
			var isApplied = IsApplied;

			var bindingContext = src ?? Context ?? context;
			base.Apply(bindingContext, bindObj, targetProperty, fromBindingContextChanged, specificity);

			if (src != null && isApplied && fromBindingContextChanged)
				return;

			if (Source is RelativeBindingSource relativeBindingSource)
			{
				var relativeSourceTarget = RelativeSourceTargetOverride ?? bindObj as Element;
				if (relativeSourceTarget is not Element)
				{
					var message = bindObj is not null
						? $"Cannot apply relative binding to {bindObj.GetType().FullName} because it is not a superclass of Element."
						: "Cannot apply relative binding when the target object is null.";

					throw new InvalidOperationException(message);
				}

				ApplyRelativeSourceBinding(relativeBindingSource, relativeSourceTarget, bindObj, targetProperty, specificity);
			}
			else
			{
				if (_expression == null)
					_expression = new BindingExpression(this, SelfPath);
				_expression.Apply(bindingContext, bindObj, targetProperty, specificity);
			}
		}

#pragma warning disable RECS0165 // Asynchronous methods should return a Task instead of void
		async void ApplyRelativeSourceBinding(RelativeBindingSource relativeSource, Element relativeSourceTarget, BindableObject targetObject, BindableProperty targetProperty, SetterSpecificity specificity)
#pragma warning restore RECS0165 // Asynchronous methods should return a Task instead of void
		{
			try
			{

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Ensure the target BindableObject is non-null before applying a relative binding.
  2. Set RelativeSourceTargetOverride to a known Element when the natural target may be transient.
  3. Defer binding application until the target element is fully constructed/loaded.

Example fix

// before
binding.Apply(context, target: null, bp, false, specificity);

// after
if (bindObj is null) return; // guard before applying a relative binding
binding.Apply(context, bindObj, bp, false, specificity);
Defensive patterns

Strategy: validation

Validate before calling

if (bindObj is null)
    return; // do not apply a relative binding without a target Element
binding.Apply(context, bindObj, bp, false, specificity);

Type guard

static bool HasValidRelativeTarget(Microsoft.Maui.Controls.BindableObject target,
    Microsoft.Maui.Controls.Element overrideEl) =>
    (overrideEl ?? target as Microsoft.Maui.Controls.Element) is not null;

Prevention

When it happens

Trigger: Calling Apply / SetBinding with a relative-source Binding before the target BindableObject is set (the framework passing a null target); setting RelativeSourceTargetOverride to null explicitly while bindObj is null; a binding applied during teardown when the target has been released.

Common situations: Framework lifecycle races where Apply is invoked during disposal; custom hosts that call SetBinding with a null target by mistake; unit tests that construct a Binding and call Apply(null, ...).

Related errors


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