dotnet/wpf · error · InvalidOperationException

SR.TextSchema_CannotInsertContentInThisPosition

Error message

SR.TextSchema_CannotInsertContentInThisPosition

What it means

Thrown by CreateInsertionPositionInIncompleteContent when an insertion position cannot be created because the position's ancestor chain contains no parentable element (parent == null). Per the source comment, this only happens when an unparented TextContainer contains only LineBreaks or InlineUIContainers, so there is no valid spot to insert a Run. The library treats this as an unrecoverable structural state (the comment notes it should be an Invariant.Assert).

Solutions

  1. Ensure the target TextContainer is attached to a parent (e.g. the TextBox/RichTextBox document flow) and contains at least one element that can host an inline Run before calling insertion APIs
  2. Inspect the document content: replace bare-only LineBreaks/InlineUIContainers with at least one Paragraph/Run so a valid insertion position exists
  3. Use TextPointer move/normalize APIs (GetInsertionPosition / GetTextInsertionPosition) to verify a valid insertion position exists before editing
  4. Wrap the edit in try-catch for InvalidOperationException and repair/rebuild the document content before retrying

Example fix

// before
TextRange range = new TextRange(textBox.Document.ContentStart, textBox.Document.ContentEnd);
range.Text = "\n\n"; // only line breaks -> later edits cannot create insertion position
// after
range.Text = "\n\n";
if (range.End.GetTextInsertionPosition().HasValidLayout == false && IsUnparentedLineBreakOnlyContainer(textBox.Document))
{
    textBox.Document = BuildDocumentWithParagraph(); // ensure a Paragraph/Run exists
}
Defensive patterns

Strategy: validation

Validate before calling

static bool CanInsert(TextPointer pos) => pos.TextContainer.Parent != null && !IsOnlyLineBreaksOrUIContainers(pos.TextContainer);

Type guard

static bool HasParentedContent(TextEditor editor) => editor?.TextContainer?.Parent != null && editor.TextContainer.Start.GetNextContextPosition(LogicalDirection.Forward) != null;

Try / catch

try { range.InsertText(text); } catch (InvalidOperationException ex) when (ex.Message.Contains("CannotInsertContent")) { RebuildDocumentHost(); }

Prevention

When it happens

Trigger: Calling EnsureInsertionPosition (via TextRange edit APIs like InsertText/ApplyPropertyValue) on a TextContainer/TextEditor whose content contains only LineBreaks (newline characters) or InlineUIContainers with no parented text elements, so no Implicit Run position can be created.

Common situations: Programmatic TextRange edits against a TextBox/RichTextBox populated with bare newline content or custom InlineUIContainer content; editing a document fragment constructed without a parent structure; copy/paste of content stripped of Run elements.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRangeEditTables.cs:871

                    // Creating implicit ListItem
                    ListItem listItem = new ListItem();
                    listItem.Reposition(position, position);
                    position = listItem.ContentStart;
                    parent = position.Parent;
                }

                if (parent is LineBreak || parent is InlineUIContainer)
                {
                    position = ((Inline)parent).ElementStart;
                    parent = position.Parent;
                }
            }

            if (parent == null)
            {
                // This should be an Invariant.Assert
                // This could happen only in case when unparented TextContainer contains only LineBreaks or InlineUIContainers
                throw new InvalidOperationException(SR.TextSchema_CannotInsertContentInThisPosition);
            }

            TextPointer insertionPosition;
            if (TextSchema.IsValidChild(/*position:*/position, /*childType:*/typeof(Inline)))
            {
                insertionPosition = CreateImplicitRun(position);
            }
            else
            {
                Invariant.Assert(TextSchema.IsValidChild(/*position:*/position, /*childType:*/typeof(Block)), "Expecting valid parent-child relationship");
                insertionPosition = CreateImplicitParagraph(position);
            }

            return insertionPosition;
        }

        // Helper for EnsureInsertionPosition, inserts a Run element at this position.
        private static TextPointer CreateImplicitRun(TextPointer position)

View on GitHub (pinned to 81131a70a4)