{"record":{"id":"fea124e752207bb8","repo":"AvaloniaUI/Avalonia","slug":"nameof-textlength-0-must-be-a-non-zero-valu","errorCode":null,"errorMessage":"{nameof(textLength)} ('0') must be a non-zero value. ","messagePattern":"(.+?) \\('0'\\) must be a non-zero value\\. ","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs","lineNumber":677,"sourceCode":"                    break;\n                }\n\n                if (nextRun is DrawableTextRun nextDrawable)\n                {\n                    directionalWidth += nextDrawable.Size.Width;\n                }\n\n                lastRunIndex = nextIndexedRun.RunIndex;\n            }\n\n            return lastRunIndex;\n        }\n\n        public override IReadOnlyList<TextBounds> GetTextBounds(int firstTextSourceIndex, int textLength)\n        {\n            if (textLength == 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(textLength), textLength, $\"{nameof(textLength)} ('0') must be a non-zero value. \");\n            }\n\n            if (_indexedTextRuns is null || _indexedTextRuns.Count == 0)\n            {\n                return [];\n            }\n\n            var currentPosition = FirstTextSourceIndex;\n            var remainingLength = textLength;\n\n            //We can return early if the requested text range is before the line's text range.\n            if (firstTextSourceIndex + textLength < FirstTextSourceIndex)\n            {\n                var indexedTextRun = _indexedTextRuns[0];\n                var currentDirection = GetRunDirection(indexedTextRun.TextRun, _resolvedFlowDirection);\n\n                return [new TextBounds(new Rect(0, 0, 0, Height), currentDirection, [])];\n            }","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs#L659-L695","documentation":"Thrown by TextLineImpl.GetTextBounds when textLength is exactly zero. GetTextBounds computes the bounding rectangles for a range of characters within a formatted text line; a zero-length range has no meaningful bounds, so Avalonia rejects it outright. The caller must request a non-zero character span.","triggerScenarios":"Calling textLine.GetTextBounds(firstTextSourceIndex, 0) — i.e. passing a textLength of zero to an already-formatted TextLine instance. Common when the length is computed from a subtraction that yields zero, or when a measurement routine is called with an empty selection range.","commonSituations":"Text selection/caret-hit-testing code that computes length as (end - start) and passes it through without clamping; caret positioned at start==end producing a zero-length bounds request; automated layout passes that probe with zero-length ranges.","solutions":["Guard the call site: if (textLength == 0) return an empty bounds list instead of calling GetTextBounds.","Ensure the computed textLength is always at least 1 when a real range is intended.","If performing caret hit-testing with a degenerate (empty) selection, skip the GetTextBounds call entirely."],"exampleFix":"// before\nvar bounds = line.GetTextBounds(startIndex, endIndex - startIndex); // throws when equal\n\n// after\nvar length = endIndex - startIndex;\nvar bounds = length > 0\n    ? line.GetTextBounds(startIndex, length)\n    : Array.Empty<TextBounds>();","handlingStrategy":"validation","validationCode":"static IReadOnlyList<TextBounds> SafeGetBounds(TextLine line, int first, int len)\n{\n    if (len <= 0) return Array.Empty<TextBounds>();\n    return line.GetTextBounds(first, len);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp computed text lengths to a minimum of 1 before calling GetTextBounds.","Skip bounds queries for degenerate (zero-length) selections.","Centralize selection-length computation to avoid raw subtraction at call sites."],"tags":["text-formatting","text-bounds","argument-validation","avalonia"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}