{"record":{"id":"93213c1f7619cde8","repo":"dotnet/wpf","slug":"argumentoutofrangeexception-nameof-characterhit","errorCode":null,"errorMessage":"ArgumentOutOfRangeException(nameof(characterHit))","messagePattern":"ArgumentOutOfRangeException\\(nameof\\(characterHit\\)\\)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphRun.cs","lineNumber":482,"sourceCode":"\n        /// <summary>\n        /// Given a character hit, computes the offset from the leading edge of the glyph run\n        /// to the leading or trailing edge of a caret stop containing the character hit.\n        /// If the glyph run is not hit testable, the distance of 0.0 is returned.\n        /// </summary>\n        /// <param name=\"characterHit\">Character hit to compute the distance to.</param>\n        /// <returns>The offset from the leading edge of the glyph run\n        /// to the leading or trailing edge of a caret stop containing the character hit.</returns>\n        /// <exception cref=\"System.ArgumentOutOfRangeException\">\n        /// The input character hit is outside of the range specified by the glyph run Unicode string.\n        /// </exception>\n        public double GetDistanceFromCaretCharacterHit(CharacterHit characterHit)\n        {\n            CheckInitialized(); // This can only be called on fully initialized GlyphRun\n\n            IList<bool> caretStops = CaretStops != null && CaretStops.Count != 0 ? CaretStops : new DefaultCaretStopList(CodepointCount);\n            if (characterHit.FirstCharacterIndex < 0 || characterHit.FirstCharacterIndex > CodepointCount)\n                throw new ArgumentOutOfRangeException(nameof(characterHit));\n\n            int caretStopIndex, codePointsUntilNextStop;\n            FindNearestCaretStop(\n                characterHit.FirstCharacterIndex,\n                caretStops,\n                out caretStopIndex,\n                out codePointsUntilNextStop);\n\n            // Not a hit testable glyph run.\n            if (caretStopIndex == -1)\n                return 0.0;\n\n            // Trailing edge of a caret stop that doesn't have a corresponding valid next caret stop.\n            if (codePointsUntilNextStop == -1 && characterHit.TrailingLength != 0)\n            {\n                return 0.0;\n            }\n","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphRun.cs#L464-L500","documentation":"GetDistanceFromCaretCharacterHit throws ArgumentOutOfRangeException when the CharacterHit's FirstCharacterIndex is negative or greater than the GlyphRun's CodepointCount. Only character hits that fall inside the run's codepoint range are meaningful for caret distance measurement. The method checks this right after confirming the run is fully initialized.","triggerScenarios":"Calling glyphRun.GetDistanceFromCaretCharacterHit(new CharacterHit(-1, ...)) or with FirstCharacterIndex > glyphRun.CodepointCount. Typically a hit produced for a different GlyphRun or text source is passed to this run.","commonSituations":"Hit-testing code that maps a mouse position to a character hit on one run but measures distance on another; caching CharacterHit values across text layout rebuilds where CodepointCount changed; off-by-one arithmetic computing the hit index from character offsets.","solutions":["Clamp or validate characterHit.FirstCharacterIndex to [0, glyphRun.CodepointCount] before calling.","Ensure the CharacterHit originates from the same GlyphRun/text layout instance used for the distance query.","Recompute character hits after any text content or layout change rather than reusing stale ones."],"exampleFix":"// before\ndouble d = run.GetDistanceFromCaretCharacterHit(hit);\n// after\nif (hit.FirstCharacterIndex < 0 || hit.FirstCharacterIndex > run.CodepointCount)\n    hit = new CharacterHit(Math.Max(0, Math.Min(hit.FirstCharacterIndex, run.CodepointCount)));\ndouble d = run.GetDistanceFromCaretCharacterHit(hit);","handlingStrategy":"validation","validationCode":"bool inRange = characterHit.FirstCharacterIndex >= 0 && characterHit.FirstCharacterIndex <= glyphRun.CodepointCount;\nif (!inRange) characterHit = new CharacterHit(Math.Clamp(characterHit.FirstCharacterIndex, 0, glyphRun.CodepointCount));","typeGuard":"bool IsValidHit(GlyphRun run, CharacterHit hit) => hit.FirstCharacterIndex >= 0 && hit.FirstCharacterIndex <= run.CodepointCount;","tryCatchPattern":"try { d = run.GetDistanceFromCaretCharacterHit(hit); }\ncatch (ArgumentOutOfRangeException) { d = 0; hit = new CharacterHit(0); }","preventionTips":["Keep CharacterHit values paired with the GlyphRun instance they came from.","Invalidate cached hits whenever the text source or layout is rebuilt.","Clamp indices with Math.Clamp before any caret math."],"tags":["wpf","glyphrun","argument-out-of-range","caret"],"backgroundTag":"argument-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}