{"record":{"id":"0571e1dc7ddb3709","repo":"dotnet/maui","slug":"value-is-an-invalid-value-for-property-propertyna","errorCode":null,"errorMessage":"Value is an invalid value for {property.PropertyName}","messagePattern":"Value is an invalid value for (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/BindableObject.cs","lineNumber":864,"sourceCode":"\t\t\tCoerceValue(propertyKey.BindableProperty, checkAccess: false);\n\t\t}\n\n\t\tvoid CoerceValue(BindableProperty property, bool checkAccess)\n\t\t{\n\t\t\tif (property == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(property));\n\n\t\t\tif (checkAccess && property.IsReadOnly)\n\t\t\t\tthrow new InvalidOperationException($\"The BindableProperty \\\"{property.PropertyName}\\\" is readonly.\");\n\n\t\t\tBindablePropertyContext bpcontext = GetContext(property);\n\t\t\tif (bpcontext == null)\n\t\t\t\treturn;\n\n\t\t\tobject currentValue = bpcontext.Values.GetValue();\n\n\t\t\tif (property.ValidateValue != null && !property.ValidateValue(this, currentValue))\n\t\t\t\tthrow new ArgumentException($\"Value is an invalid value for {property.PropertyName}\", nameof(currentValue));\n\n\t\t\tproperty.CoerceValue?.Invoke(this, currentValue);\n\t\t}\n\n\t\t[Flags]\n\t\tinternal enum BindableContextAttributes\n\t\t{\n\t\t\tIsBeingSet = 1 << 1,\n\t\t\t//GO AWAY\n\t\t\tIsDynamicResource = 1 << 2,\n\t\t\tIsSetFromStyle = 1 << 3,\n\t\t\tIsDefaultValueCreated = 1 << 5,\n\t\t}\n\n\t\tinternal sealed class BindablePropertyContext\n\t\t{\n\t\t\tpublic BindableContextAttributes Attributes;\n","sourceCodeStart":846,"sourceCodeEnd":882,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/BindableObject.cs#L846-L882","documentation":"ArgumentException thrown by CoerceValue when the property's ValidateValue delegate rejects the current value after coercion, with message 'Value is an invalid value for {property.PropertyName}' and paramName 'currentValue'. This means the stored value violates the validation predicate registered on the BindableProperty (e.g. a range constraint). Coercion is meant to keep values valid, so a post-coerce validation failure indicates the coerce logic and validate logic disagree, or the value was set out-of-band.","triggerScenarios":"A BindableProperty with both a CoerceValue (clamping) and a ValidateValue callback where coercion still leaves an invalid value; setting a value directly that bypasses validation (e.g. via SetValueCore) then coercing; coercion callback not actually fixing the value.","commonSituations":"Sliders/numeric controls with range validation; custom controls where the coerce and validate constraints were edited independently and drifted; values pushed during deserialization that violate runtime invariants.","solutions":["Ensure the CoerceValue callback always returns a value that satisfies ValidateValue (clamp to the valid range, not just toward it).","Do not bypass validation when setting values; route writes through SetValue so ValidateValue runs.","If using SetValueCore with Converted/private flags, re-validate before coercing."],"exampleFix":"// before\n// coerce returns value unchanged even when out of range\nstatic object Coerce(BindableObject b, object v) => v;\n// after\nstatic object Coerce(BindableObject b, object v)\n{\n    var d = (double)v;\n    return Math.Clamp(d, Min, Max); // satisfies ValidateValue(range)\n}","handlingStrategy":"try-catch","validationCode":"// Validate against the same constraint the property uses before coercing\nif (property.ValidateValue is not null && !property.ValidateValue(obj, candidate))\n    candidate = ClampToValid(candidate);","typeGuard":null,"tryCatchPattern":"try { obj.CoerceValue(property); }\ncatch (ArgumentException ex) when (ex.ParamName == \"currentValue\")\n{ /* coerce/validate disagree; reset to default or log */ }","preventionTips":["Keep CoerceValue and ValidateValue callbacks consistent — coerce must always land inside the valid range.","Never set values through SetValueCore in a way that bypasses ValidateValue."],"tags":["maui","coerce","validation","argument","bindableproperty"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}