{"record":{"id":"aed201449d6c0016","repo":"AvaloniaUI/Avalonia","slug":"invalid-size-returned-for-measure","errorCode":null,"errorMessage":"Invalid size returned for Measure.","messagePattern":"Invalid size returned for Measure\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Layout/Layoutable.cs","lineNumber":396,"sourceCode":"\n                var previousDesiredSize = DesiredSize;\n                var desiredSize = default(Size);\n\n                IsMeasureValid = true;\n\n                try\n                {\n                    _measuring = true;\n                    desiredSize = MeasureCore(availableSize);\n                }\n                finally\n                {\n                    _measuring = false;\n                }\n\n                if (IsInvalidSize(desiredSize))\n                {\n                    throw new InvalidOperationException(\"Invalid size returned for Measure.\");\n                }\n\n                DesiredSize = desiredSize;\n                _previousMeasure = availableSize;\n\n                Logger.TryGet(LogEventLevel.Verbose, LogArea.Layout)?.Log(this, \"Measure requested {DesiredSize}\", DesiredSize);\n\n                if (DesiredSize != previousDesiredSize)\n                {\n                    this.GetVisualParent<Layoutable>()?.ChildDesiredSizeChanged(this);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Arranges the control and its children.\n        /// </summary>\n        /// <param name=\"rect\">The control's new bounds.</param>","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Layout/Layoutable.cs#L378-L414","documentation":"Measure throws after MeasureCore returns a Size whose Width or Height is negative or non-finite (NaN/Infinity). This is the contract check on the OUTPUT of measure: subclasses overriding MeasureCore must return a valid, non-negative, finite desired size. Infinity or NaN in DesiredSize would corrupt every parent's measure math.","triggerScenarios":"A custom Layoutable subclass whose MeasureCore override returns a Size with a negative component, NaN, or Infinity. Can also indicate arithmetic in the override that divided by zero or returned an uninitialized Size.","commonSituations":"Writing a custom control/panel and returning `new Size(double.NaN, ...)` or a negative value from MeasureCore/MeasureOverride. Forgetting to clamp a computed desired size. Returning DesiredSize before it was set.","solutions":["In the MeasureCore/MeasureOverride override, ensure the returned Size has non-negative, finite Width and Height.","Clamp computed values: Math.Max(0, value) and guard against NaN/Infinity before returning.","If a child measure failed, fall back to a sensible default size rather than propagating an invalid result."],"exampleFix":"// before\nprotected override Size MeasureCore(Size availableSize)\n{\n    return new Size(DesiredSize.Width / someDivisorThatIsZero, height);\n}\n\n// after\nprotected override Size MeasureCore(Size availableSize)\n{\n    var w = someDivisor != 0 ? DesiredSize.Width / someDivisor : 0;\n    return new Size(Math.Max(0, w), height);\n}","handlingStrategy":"validation","validationCode":"// Inside a MeasureCore/MeasureOverride override, validate the return value:\nstatic Size Valid(Size s) => new Size(\n    double.IsNaN(s.Width) || s.Width < 0 ? 0 : s.Width,\n    double.IsNaN(s.Height) || s.Height < 0 ? 0 : s.Height);\n\nreturn Valid(computedDesiredSize);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always clamp MeasureCore/MeasureOverride return values to non-negative finite sizes.","Guard divisions that could produce NaN/Infinity before returning.","Unit-test custom controls' measure output with edge-case available sizes."],"tags":["layout","measure","custom-control","measurecore"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}