dotnet/wpf · error · ArgumentOutOfRangeException
InvalidDrawingAttributesWidth
Error message
InvalidDrawingAttributesWidth
What it means
ExtendedPropertySerializer rejects a value assigned to a DrawingAttributes extended property (Width/Height guid) whose double value is NaN, negative-below MinWidth, or above DrawingAttributes.MaxWidth. The library enforces the documented DrawingAttributes width range before persisting to ISF. It is an ArgumentOutOfRangeException naming the offending parameter.
Solutions
- Validate the double before assigning: check !double.IsNaN && >= DrawingAttributes.MinWidth && <= DrawingAttributes.MaxWidth
- Clamp the value: Math.Max(DrawingAttributes.MinWidth, Math.Min(DrawingAttributes.MaxWidth, value))
- Replace NaN with a sane default such as DrawingAttributes.DefaultWidth
- Guard upstream data sources (config, files, network) that feed widths
Example fix
// before
attr.AddPropertyData(CustomAttributeSerializer.CurrentWidthGuid, computedWidth); // may be NaN/negative
// after
if (!double.IsNaN(computedWidth) && computedWidth >= DrawingAttributes.MinWidth && computedWidth <= DrawingAttributes.MaxWidth)
attr.AddPropertyData(CustomAttributeSerializer.CurrentWidthGuid, computedWidth);
else
attr.Width = DrawingAttributes.DefaultWidth; Defensive patterns
Strategy: validation
Validate before calling
static bool IsValidWidth(double w) => !double.IsNaN(w) && !double.IsInfinity(w) && w >= System.Windows.Ink.DrawingAttributes.MinWidth && w <= System.Windows.Ink.DrawingAttributes.MaxWidth;
Type guard
static bool IsFiniteInRange(double v, double min, double max) => double.IsFinite(v) && v >= min && v <= max;
Try / catch
try { attr.AddPropertyData(widthGuid, value); }
catch (ArgumentOutOfRangeException) { attr.Width = System.Windows.Ink.DrawingAttributes.DefaultWidth; } Prevention
- Always clamp user/computed widths into [MinWidth, MaxWidth]
- Reject or replace NaN/Infinity before assigning extended properties
- Centralize width assignment in one validated setter
- Add boundary unit tests for width serialization
When it happens
Trigger: Calling ExtendedPropertySerializer.SaveAsBaseValue or DrawingAttributes extended-property serialization with value = double.NaN, a negative width, or a value > DrawingAttributes.MaxWidth for the Width (or Height-family) guid.
Common situations: Computing a stroke width from user input or math that yields NaN (e.g. 0/0) or negative values; deserializing config or older files with unvalidated widths; unit tests probing boundary values.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- ArgumentOutOfRangeException(nameof(percentageWithinBounds))
- ArgumentOutOfRangeException(nameof(percentageWithinLasso))
- ArgumentOutOfRangeException(percentageWithinBounds)
- ArgumentOutOfRangeException(percentageWithinLasso)
- Cannot initialize compressor.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/2567543c5444f627.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/CustomAttributeSerializer.cs:868
if ( value.GetType() != typeof(double) )
{
throw new ArgumentException(SR.Format(SR.InvalidValueType, typeof(double)), nameof(value));
}
double dVal = (double)value;
if (id == KnownIds.StylusHeight)
{
if ( Double.IsNaN(dVal) || dVal < DrawingAttributes.MinHeight || dVal > DrawingAttributes.MaxHeight)
{
throw new ArgumentOutOfRangeException(nameof(value), SR.InvalidDrawingAttributesHeight);
}
}
else
{
if (Double.IsNaN(dVal) || dVal < DrawingAttributes.MinWidth || dVal > DrawingAttributes.MaxWidth)
{
throw new ArgumentOutOfRangeException(nameof(value), SR.InvalidDrawingAttributesWidth);
}
}
}
else if ( id == KnownIds.Transparency )
{
if ( value.GetType() != typeof(byte) )
{
throw new ArgumentException(SR.Format(SR.InvalidValueType, typeof(byte)), nameof(value));
}
double dVal = (double)value;
}
else
{
if ( !UsesEmbeddedTypeInformation(id) )
{
// if this guid used the legacy internal attribute persistence APIs,
// then it doesn't include embedded type information (it's always a byte array)View on GitHub (pinned to 81131a70a4)