{"record":{"id":"ce1364b4b6881fe5","repo":"dotnet/maui","slug":"propertyname","errorCode":null,"errorMessage":"propertyName","messagePattern":"propertyName","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/BindableProperty.cs","lineNumber":193,"sourceCode":"\t\t\t{ typeof(char), new[] { typeof(string), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } },\n\t\t\t{ typeof(float), new[] { typeof(string), typeof(double) } },\n\t\t\t{ typeof(ulong), new[] { typeof(string), typeof(float), typeof(double), typeof(decimal) } },\n\t\t\t{ typeof(double), new[] { typeof(string) } },\n\t\t\t{ typeof(bool), new[] { typeof(string) } },\n\t\t};\n\n\t\t/// <summary>A sentinel object used to indicate that a BindableProperty value has not been set.</summary>\n\t\tpublic static readonly object UnsetValue = new object();\n\n\t\tprivate static int _nextInternalId = int.MinValue;\n\t\tinternal readonly int InternalId;\n\n\t\tBindableProperty(string propertyName, [DynamicallyAccessedMembers(ReturnTypeMembers)] Type returnType, [DynamicallyAccessedMembers(DeclaringTypeMembers)] Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay,\n\t\t\t\t\t\t\t\t ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null,\n\t\t\t\t\t\t\t\t CoerceValueDelegate coerceValue = null, BindablePropertyBindingChanging bindingChanging = null, bool isReadOnly = false, CreateDefaultValueDelegate defaultValueCreator = null)\n\t\t{\n\t\t\tif (propertyName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(propertyName));\n\t\t\tif (returnType is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(returnType));\n\t\t\tif (declaringType is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(declaringType));\n\t\t\t\n\t\t\tInternalId = Interlocked.Increment(ref _nextInternalId);\n\n\t\t\t// don't use Enum.IsDefined as its redonkulously expensive for what it does\n\t\t\tif (defaultBindingMode != BindingMode.Default && defaultBindingMode != BindingMode.OneWay && defaultBindingMode != BindingMode.OneWayToSource && defaultBindingMode != BindingMode.TwoWay && defaultBindingMode != BindingMode.OneTime)\n\t\t\t\tthrow new ArgumentException($\"Not a valid type of BindingMode. Property: {returnType} {declaringType.Name}.{propertyName}. Default binding mode: {defaultBindingMode}\", nameof(defaultBindingMode));\n\n\t\t\tif (defaultValue == null && Nullable.GetUnderlyingType(returnType) == null && returnType.IsValueType)\n\t\t\t\tdefaultValue = Activator.CreateInstance(returnType);\n\n\t\t\tif (defaultValue != null && !returnType.IsInstanceOfType(defaultValue))\n\t\t\t\tthrow new ArgumentException($\"Default value did not match return type. Property: {returnType} {declaringType.Name}.{propertyName} Default value type: {defaultValue.GetType().Name}, \", nameof(defaultValue));\n\n\t\t\tif (defaultBindingMode == BindingMode.Default)","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/BindableProperty.cs#L175-L211","documentation":"Argument null guard in the private BindableProperty constructor: propertyName must not be null. BindableProperty.Create forwards all of its arguments here, so any Create call (or CreateAttached/CreateReadOnly) that passes a null name hits this ArgumentNullException before any field is set.","triggerScenarios":"Calling BindableProperty.Create(propertyName: null, ...) or CreateAttached(..., propertyName: null, ...); passing nameof() on a symbol that resolved to null in a refactor; dynamically building the name string and letting it be null.","commonSituations":"Refactoring a property and renaming it while the nameof() target was deleted; copy-paste between Create and CreateAttached that drops the name argument; code generation that emits a null name under some branch.","solutions":["Pass a non-null propertyName (typically nameof(MyProperty)) to BindableProperty.Create.","If the name comes from a computed string, validate it is non-null before the call.","Add a unit test asserting the BindableProperty field is non-null after static initialization."],"exampleFix":"// before\npublic static readonly BindableProperty TitleProperty =\n    BindableProperty.Create(null, typeof(string), typeof(MyView));\n\n// after\npublic static readonly BindableProperty TitleProperty =\n    BindableProperty.Create(nameof(Title), typeof(string), typeof(MyView));","handlingStrategy":"validation","validationCode":"if (propertyName is null) throw new ArgumentNullException(nameof(propertyName));\nvar bp = BindableProperty.Create(propertyName, typeof(string), typeof(MyView));","typeGuard":"static bool IsValidPropertyName(string name) => !string.IsNullOrWhiteSpace(name);","tryCatchPattern":null,"preventionTips":["Always use nameof(SomeProperty) for the property name argument.","Add a static-constructor unit test asserting all BindableProperty fields are non-null."],"tags":["maui","bindableproperty","argument-validation","nullable"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}