dotnet/wpf · error · InvalidOperationException

SR.Format(SR.UIElement_Layout_PositiveInfinityReturned…

Error message

SR.Format(SR.UIElement_Layout_PositiveInfinityReturned, this.GetType().FullName)

What it means

After MeasureCore returns, UIElement.Measure validates the desiredSize and throws InvalidOperationException if width or height is PositiveInfinity, even when infinite available size was given. A MeasureCore implementation must always return a finite desired size; infinity is not a legal measure result.

Solutions

  1. Fix MeasureOverride to return a finite desired size (e.g. clamp or measure content with the constraint).
  2. Never return availableSize itself when it is infinite; measure children and sum finite results.
  3. Use double.IsInfinity in custom code to sanitize the returned Size.

Example fix

// before
protected override Size MeasureOverride(Size available) => available; // may be infinite
// after
protected override Size MeasureOverride(Size available)
{
    child.Measure(available);
    return new Size(Math.Min(child.DesiredSize.Width, available.Width), child.DesiredSize.Height);
}
Defensive patterns

Strategy: validation

Validate before calling

var d = MeasureOverrideCore(available);
if (double.IsPositiveInfinity(d.Width) || double.IsPositiveInfinity(d.Height))
    d = new Size(Math.Min(d.Width, available.Width), Math.Min(d.Height, available.Height));

Type guard

bool IsFiniteDesiredSize(Size s) => !double.IsInfinity(s.Width) && !double.IsInfinity(s.Height) && !double.IsNaN(s.Width) && !double.IsNaN(s.Height);

Try / catch

try { element.Measure(available); } catch (InvalidOperationException ex) when (ex.Message.Contains("PositiveInfinity")) { /* fix MeasureOverride of the named type */ }

Prevention

When it happens

Trigger: A custom FrameworkElement/panel whose MeasureOverride returns Size(double.PositiveInfinity, ...) or propagates the infinite constraint back as desired size.

Common situations: Custom controls returning the availableSize directly instead of a finite measured size; content-based elements measuring 'infinite' children and forwarding infinity.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/02124b4236417651. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/UIElement.cs:672

                        _previousAvailableSize = availableSize;

                        layoutManager.ExitMeasure();

                        if (gotException)
                        {
                            // we don't want to reset last exception element on layoutManager if it's been already set.
                            if (layoutManager.GetLastExceptionElement() == null)
                            {
                                layoutManager.SetLastExceptionElement(this);
                            }
                        }
                    }

                    //enforce that MeasureCore can not return PositiveInfinity size even if given Infinte availabel size.
                    //Note: NegativeInfinity can not be returned by definition of Size structure.
                    if (double.IsPositiveInfinity(desiredSize.Width) || double.IsPositiveInfinity(desiredSize.Height))
                        throw new InvalidOperationException(SR.Format(SR.UIElement_Layout_PositiveInfinityReturned, this.GetType().FullName));

                    //enforce that MeasureCore can not return NaN size .
                    if (double.IsNaN(desiredSize.Width) || double.IsNaN(desiredSize.Height))
                        throw new InvalidOperationException(SR.Format(SR.UIElement_Layout_NaNReturned, this.GetType().FullName));

                    //reset measure dirtiness

                    MeasureDirty = false;
                    //reset measure request.
                    if (MeasureRequest != null)
                        ContextLayoutManager.From(Dispatcher).MeasureQueue.Remove(this);

                    //cache desired size
                    _desiredSize = desiredSize;

                    //notify parent if our desired size changed (watefall effect)
                    if (!MeasureDuringArrange
                       && !DoubleUtil.AreClose(prevSize, desiredSize))

View on GitHub (pinned to 81131a70a4)