dotnet/wpf · error · InvalidOperationException

SR.TextSchema_UIElementNotAllowedInThisPosition

Error message

SR.TextSchema_UIElementNotAllowedInThisPosition

What it means

TextPointer.InsertUIElement inserts a UIElement as an embedded object at the pointer's position. WPF requires the enclosing element to be empty (an InlineUIContainer or BlockUIContainer that already has content cannot host another child), so when this.Parent is a non-empty TextElement it throws InvalidOperationException(SR.TextSchema_UIElementNotAllowedInThisPosition).

Solutions

  1. Check ((TextElement)pointer.Parent).IsEmpty before calling InsertUIElement, or create a fresh InlineUIContainer at a new position.
  2. Move the TextPointer to an empty insertion point (e.g. after the existing element) before inserting.
  3. Wrap in try/catch for InvalidOperationException and fall back to inserting a new Run/container.

Example fix

// before
pointer.InsertUIElement(myImage);
// after
if (pointer.Parent is TextElement te && te.IsEmpty)
    pointer.InsertUIElement(myImage);
else {
    var container = new InlineUIContainer(myImage);
    ((Paragraph)pointer.Parent).Inlines.InsertBefore(pointer.GetAdjacentElement(LogicalDirection.Backward) as Inline, container);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!(pointer.Parent is TextElement parent) || !parent.IsEmpty)
    throw new InvalidOperationException("Position cannot host a UIElement.");

Type guard

static bool CanInsertUIElement(TextPointer p) => p.Parent is TextElement te && te.IsEmpty;

Try / catch

try { pointer.InsertUIElement(element); }
catch (InvalidOperationException) { /* reposition into a fresh InlineUIContainer and retry */ }

Prevention

When it happens

Trigger: Calling InsertUIElement on a TextPointer whose parent TextElement is a non-empty InlineUIContainer/BlockUIContainer, or whose position does not permit embedded objects per the text schema.

Common situations: Programmatically inserting images/controls into a RichTextBox FlowDocument at a position that already contains a UIElement; inserting at a position where validation placed the pointer inside a populated container.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextPointer.cs:2147

        /// The LogicalDirection property specifies whether this TextPointer
        /// will be positioned before or after the UIElement.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// Throws ArgumentException is contentElement is not valid
        /// according to flow schema.
        /// </exception>
        internal void InsertUIElement(UIElement uiElement)
        {
            ArgumentNullException.ThrowIfNull(uiElement);

            _tree.EmptyDeadPositionList();
            SyncToTreeGeneration();

            ValidationHelper.ValidateChild(this, uiElement, nameof(uiElement));

            if (!((TextElement)this.Parent).IsEmpty) // the parent may be InlineUIContainer or BlockUIContainer
            {
                throw new InvalidOperationException(SR.TextSchema_UIElementNotAllowedInThisPosition);
            }

            _tree.BeginChange();
            try
            {
                _tree.InsertEmbeddedObjectInternal(this, uiElement);
            }
            finally
            {
                _tree.EndChange();
            }
        }

        // consider adding this to public API.
        internal TextElement GetAdjacentElementFromOuterPosition(LogicalDirection direction)
        {
            TextTreeTextElementNode elementNode;

View on GitHub (pinned to 81131a70a4)