dotnet/wpf · error · ArgumentException

nameof(segmentNumber)

Error message

nameof(segmentNumber)

What it means

TextSelectionProcessor.GetLocatorPartSegmentValues throws ArgumentException(nameof(segmentNumber)) when segmentNumber is negative. Segment attributes are keyed 'Segment0','Segment1',... so a negative index is invalid by contract; the exception's parameter name is reported as 'segmentNumber'.

Solutions

  1. Validate segmentNumber >= 0 before calling
  2. Enumerate segments from 0 to Count-1 using the locator part's Count attribute
  3. Clamp or reject negative indices when reading persisted data

Example fix

// before
GetLocatorPartSegmentValues(part, i - 1, out s, out e);
// after
if (i - 1 >= 0) GetLocatorPartSegmentValues(part, i - 1, out s, out e);
Defensive patterns

Strategy: validation

Validate before calling

if (segmentNumber < 0)
    throw new ArgumentOutOfRangeException(nameof(segmentNumber));

Try / catch

try { GetLocatorPartSegmentValues(part, i, out s, out e); }
catch (ArgumentException ex) when (ex.ParamName == "segmentNumber") { /* skip/clamp index */ }

Prevention

When it happens

Trigger: Calling GetLocatorPartSegmentValues with a negative segmentNumber; a loop iterating to a bad Count value or computing an index from user/persisted data that underflows below zero.

Common situations: Off-by-one or underflow when enumerating segments of a locator part; corrupted Count value leading to bad index arithmetic.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Anchoring/TextSelectionProcessor.cs:434

        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        /// <summary>
        ///     Extracts the values of attributes from a locator part.
        /// </summary>
        /// <param name="locatorPart">the locator part to extract values from</param>
        /// <param name="segmentNumber">the number of the segment to extract values for</param>
        /// <param name="startOffset">value of offset attribute</param>
        /// <param name="endOffset">value of length attribute</param>
        private static void GetLocatorPartSegmentValues(ContentLocatorPart locatorPart, int segmentNumber, out int startOffset, out int endOffset)
        {
            if (segmentNumber < 0)
                throw new ArgumentException(nameof(segmentNumber));

            ReadOnlySpan<char> segmentString = locatorPart.NameValuePairs[SegmentAttribute + segmentNumber.ToString(NumberFormatInfo.InvariantInfo)].AsSpan();

            Span<Range> splitRegions = stackalloc Range[3];
            if (segmentString.Split(splitRegions, Separator) != 2)
            {
                throw new ArgumentException(SR.Format(SR.InvalidLocatorPart, SegmentAttribute + segmentNumber.ToString(NumberFormatInfo.InvariantInfo)));
            }

            startOffset = int.Parse(segmentString[splitRegions[0]], NumberFormatInfo.InvariantInfo);
            endOffset = int.Parse(segmentString[splitRegions[1]], NumberFormatInfo.InvariantInfo);
        }

        /// <summary>
        ///     Returns the TextContainer for a node that contains text.  If the node
        ///     doesn't have a TextContainer this method returns null.
        /// </summary>
        private ITextContainer GetTextContainer(DependencyObject startNode)

View on GitHub (pinned to 81131a70a4)