dotnet/maui · error · InvalidOperationException

Cannot apply relative binding to {bindObj.GetType().FullName

Error message

Cannot apply relative binding to {bindObj.GetType().FullName} because it is not a superclass of Element.

What it means

InvalidOperationException from Binding.Apply when Source is a RelativeBindingSource but the target object (after RelativeSourceTargetOverride fallback) is not a Maui Element. Relative bindings walk the visual/element tree (self, parent, ancestor-by-type), so they require an Element target; applying one to a non-Element BindableObject (or a null override) is rejected. The message reports the actual type found.

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. Apply relative bindings only on Element-derived targets (VisualElement, Page, View, etc.).
  2. If you need a non-element source, use an explicit Source or x:Static instead of RelativeBindingSource.
  3. If you set RelativeSourceTargetOverride, pass an Element.

Example fix

// before (applied to a non-Element BindableObject)
myBindableObject.SetBinding(MyProp, new Binding("X", source: RelativeBindingSource.TemplatedParent));

// after (apply on an Element, or use an explicit source)
myVisualElement.SetBinding(MyProp, new Binding("X", source: RelativeBindingSource.TemplatedParent));
Defensive patterns

Strategy: type-guard

Validate before calling

if (bindObj is not Microsoft.Maui.Controls.Element)
    throw new InvalidOperationException("Relative bindings require an Element target.");
bindObj.SetBinding(MyProp, new Binding("X", source: RelativeBindingSource.Self));

Type guard

static bool CanUseRelativeBinding(Microsoft.Maui.Controls.BindableObject target) =>
    target is Microsoft.Maui.Controls.Element;

Prevention

When it happens

Trigger: Calling SetBinding with a Binding whose Source is RelativeBindingSource.Self/Parent/FindAncestor on a BindableObject that is not an Element (e.g. a bare BindableObject, a Behavior, or a non-visual object); setting RelativeSourceTargetOverride to a non-Element.

Common situations: Trying relative source bindings on view-model-like BindableObjects; porting a relative binding that worked on a VisualElement to a non-visual object; testing bindings against mock BindableObjects.

Related errors


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