dotnet/wpf · error · InvalidOperationException
SR.Format(SR.RichEditTextPatternHasNoChildren…
Error message
SR.Format(SR.RichEditTextPatternHasNoChildren, GetType().FullName)
What it means
The rich edit control's ITextProvider exposes one whole-document text range and no child elements (hyperlinks/embedded objects are not exposed as children). RangeFromChild is therefore meaningless for this element and unconditionally throws InvalidOperationException(SR.RichEditTextPatternHasNoChildren, GetType().FullName), naming the concrete proxy type in the message.
Solutions
- Use RangeFromPoint or DocumentRange / text-unit methods (Move, FindText) instead of RangeFromChild on rich edits
- Guard: only call RangeFromChild for providers that actually expose children; check the element's supported pattern/control type first
- Restructure automation to search text via FindText on the document range rather than child traversal
Example fix
// before
var range = textPattern.RangeFromChild(childElement); // always throws for RichEdit
// after
if (isRichEdit)
var range = textPattern.DocumentRange.FindText(searchText, false, false);
else
var range = textPattern.RangeFromChild(childElement); Defensive patterns
Strategy: fallback
Validate before calling
var range = textPattern is RichEditTextPattern ? null : childElement != null ? textPattern.RangeFromChild(childElement) : null;
Type guard
bool SupportsRangeFromChild(TextPattern tp) => !(tp.GetType().Name.Contains("RichEdit")); Try / catch
try { range = textPattern.RangeFromChild(child); } catch (InvalidOperationException) { range = textPattern.DocumentRange.FindText(text, false, false); } Prevention
- Never call RangeFromChild on rich edit text providers — they expose no children
- Use DocumentRange.FindText or RangeFromPoint for locating text
- Write generic text-pattern helpers that tolerate InvalidOperationException from RangeFromChild
When it happens
Trigger: Calling ITextProvider.RangeFromChild(childElement) on a WindowsRichEdit-based Text pattern with any childElement argument — the call can never succeed.
Common situations: Generic Text-pattern helper code that walks UIA elements by calling RangeFromChild for every parent element; passing hyperlink or embedded-object automation elements assuming they are children of the rich edit.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- SR.NoITextDocumentFromRichEdit
- SR.DoesNotSupportMultipleSelection
- SR.DoesNotSupportMultipleSelection
- SR.Format(SR.NotAValidValue, str)
- SR.OperationCannotBePerformed
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/38b862b60b2df164.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsRichEdit.cs:260
else
return new ITextRangeProvider[] { new WindowsRichEditRange(range, this) };
}
ITextRangeProvider [] ITextProvider.GetVisibleRanges()
{
ITextRange range = GetVisibleRange();
if (range == null)
return Array.Empty<ITextRangeProvider>();
else
return new ITextRangeProvider[] { new WindowsRichEditRange(range, this) };
}
ITextRangeProvider ITextProvider.RangeFromChild(IRawElementProviderSimple childElement)
{
// we don't have any children so this call must be in error.
// if we implement children for hyperlinks and embedded objects then we'll need to change this.
throw new InvalidOperationException(SR.Format(SR.RichEditTextPatternHasNoChildren, GetType().FullName));
}
ITextRangeProvider ITextProvider.RangeFromPoint(Point screenLocation)
{
// we must have called EnsureTextDocument() before arriving here.
Debug.Assert(_document != null);
// TextPattern has verified that the point is inside our client area so we don't need to check for that.
// get the degenerate range at the point
// we're assuming ITextDocument::RangeFromPoint always returns a degenerate range
ITextRange range = _document.RangeFromPoint((int)screenLocation.X, (int)screenLocation.Y);
Debug.Assert(range.Start == range.End);
// if you wanted to get the character under the point instead of the degenerate range nearest
// the point, then you would add:
//// if the point is within the character to the right then expand the degenerate range toView on GitHub (pinned to 81131a70a4)