dotnet/maui · error · ArgumentNullException
returnType
Error message
returnType
What it means
Argument null guard in the private BindableProperty constructor: returnType must not be null. Reached through every BindableProperty.Create* factory whenever the value type argument is null. The property records what CLR type its values must have, so a null type makes the property unusable.
Source
Thrown at src/Controls/src/Core/BindableProperty.cs:195
{ typeof(ulong), new[] { typeof(string), typeof(float), typeof(double), typeof(decimal) } },
{ typeof(double), new[] { typeof(string) } },
{ typeof(bool), new[] { typeof(string) } },
};
/// <summary>A sentinel object used to indicate that a BindableProperty value has not been set.</summary>
public static readonly object UnsetValue = new object();
private static int _nextInternalId = int.MinValue;
internal readonly int InternalId;
BindableProperty(string propertyName, [DynamicallyAccessedMembers(ReturnTypeMembers)] Type returnType, [DynamicallyAccessedMembers(DeclaringTypeMembers)] Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay,
ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null,
CoerceValueDelegate coerceValue = null, BindablePropertyBindingChanging bindingChanging = null, bool isReadOnly = false, CreateDefaultValueDelegate defaultValueCreator = null)
{
if (propertyName == null)
throw new ArgumentNullException(nameof(propertyName));
if (returnType is null)
throw new ArgumentNullException(nameof(returnType));
if (declaringType is null)
throw new ArgumentNullException(nameof(declaringType));
InternalId = Interlocked.Increment(ref _nextInternalId);
// don't use Enum.IsDefined as its redonkulously expensive for what it does
if (defaultBindingMode != BindingMode.Default && defaultBindingMode != BindingMode.OneWay && defaultBindingMode != BindingMode.OneWayToSource && defaultBindingMode != BindingMode.TwoWay && defaultBindingMode != BindingMode.OneTime)
throw new ArgumentException($"Not a valid type of BindingMode. Property: {returnType} {declaringType.Name}.{propertyName}. Default binding mode: {defaultBindingMode}", nameof(defaultBindingMode));
if (defaultValue == null && Nullable.GetUnderlyingType(returnType) == null && returnType.IsValueType)
defaultValue = Activator.CreateInstance(returnType);
if (defaultValue != null && !returnType.IsInstanceOfType(defaultValue))
throw new ArgumentException($"Default value did not match return type. Property: {returnType} {declaringType.Name}.{propertyName} Default value type: {defaultValue.GetType().Name}, ", nameof(defaultValue));
if (defaultBindingMode == BindingMode.Default)
defaultBindingMode = BindingMode.OneWay;
View on GitHub (pinned to f377ff1c5e)
Solutions
- Pass the concrete value type as the second argument, e.g. typeof(string).
- For generic hosts, resolve the open type explicitly (typeof(T)) and confirm T is constrained.
- Guard computed Type values for null before calling Create.
Example fix
// before
public static readonly BindableProperty ValueProperty =
BindableProperty.Create(nameof(Value), _resolvedType, typeof(MyView));
// after
public static readonly BindableProperty ValueProperty =
BindableProperty.Create(nameof(Value), typeof(string), typeof(MyView)); Defensive patterns
Strategy: validation
Validate before calling
if (valueType is null) throw new ArgumentNullException(nameof(valueType)); var bp = BindableProperty.Create(nameof(X), valueType, typeof(MyView));
Type guard
static bool IsKnownValueType(Type t) => t is not null && t.IsSerializable;
Prevention
- Pass typeof(ConcreteType) literally rather than a computed Type variable.
- Recompile generic hosts after changing type constraints.
When it happens
Trigger: BindableProperty.Create(nameof(X), null, typeof(MyView)); passing a Type variable that resolved to null (e.g. from a generic whose type argument was erased); generated code that emits typeof() against an unresolved symbol.
Common situations: Building a generic control and forgetting to substitute the type argument; refactoring that leaves typeof(RemovedClass); source generators emitting null type tokens.
Related errors
- propertyName
- declaringType
- Not a valid type of BindingMode. Property: {returnType} {dec
- Default value did not match return type. Property: {returnTy
- path cannot be an empty string
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/750b69d86324c548.
Report an issue: GitHub.