dotnet/wpf · error · ArgumentException

SR.BeginEndTextContainerMismatch

Error message

SR.BeginEndTextContainerMismatch

What it means

GenerateText in the UIA WordBreaker throws ArgumentException when the begin and end TextPointer values passed to it are attached to two different text containers. Text ranges must lie within a single text container so a TextNavigator can walk from begin to end. This is an API-misuse guard inside UIAutomationClientSideProviders.

Solutions

  1. Ensure both begin and end pointers come from the same TextContainer / same element before calling.
  2. Re-fetch both pointers from the current element instead of reusing stale ones from a previous instance.
  3. Wrap the call in a try/catch for ArgumentException and fall back to per-element processing.

Example fix

// before
wordBreaker.BreakText(oldPointer, newTextPointer);
// after
if (!ReferenceEquals(oldPointer.TextContainer, newTextPointer.TextContainer))
    newTextPointer = element.CurrentTextPointer; // re-fetch from same container
wordBreaker.BreakText(oldPointer, newTextPointer);
Defensive patterns

Strategy: validation

Validate before calling

if (!ReferenceEquals(begin?.TextContainer, end?.TextContainer))
    throw new InvalidOperationException("begin/end must belong to the same text container");

Type guard

bool SameContainer(TextPointer a, TextPointer b) => a != null && b != null && ReferenceEquals(a.TextContainer, b.TextContainer);

Try / catch

try { GenerateText(begin, end); }
catch (ArgumentException ex) when (ex.Message.Contains("BeginEndTextContainerMismatch")) { /* process each container separately */ }

Prevention

When it happens

Trigger: Calling GenerateText (via BreakText) with two TextPointer instances whose .TextContainer properties differ, e.g. mixing pointers from two different text documents/elements or pointers captured before a container was rebuilt.

Common situations: Automation client code caching TextPointer values across container re-creations (document reload), or combining pointers from separate controls in a single range for word-breaking.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WordBreaker.cs:735

                return textChangedHandler;
            }
        }

        #endregion

        #region Text Helpers

        #region Navigation
        internal static string GenerateText(TextPosition begin, TextPosition end)
        {
            StringBuilder output = new StringBuilder();
            TextNavigator navigator = begin.CreateNavigator();
            TextSymbolType type;
            Span<char> buffer = stackalloc char[1];
            char ch;

            if (begin.TextContainer != end.TextContainer)
                throw new ArgumentException(SR.BeginEndTextContainerMismatch);

            navigator.MoveToPosition(begin);
            type = navigator.GetSymbolType(LogicalDirection.Forward);
            while (navigator < end)
            {
                switch (type)
                {
                    case TextSymbolType.Character:
                        navigator.GetText(LogicalDirection.Forward, 1, navigator.TextContainer.End, buffer, 0);
                        ch = buffer[0];
                        output.Append(ch);
                        break;

                    case TextSymbolType.EmbeddedObject:
                        ch = '\xF8FF';      // Private use Unicode.
                        output.Append(ch);
                        break;

View on GitHub (pinned to 81131a70a4)