dotnet/wpf · error · InvalidOperationException
SR.TextPointer_CannotInsertTextElementBecauseItBelongsToAnot…
Error message
SR.TextPointer_CannotInsertTextElementBecauseItBelongsToAnotherTree
What it means
TextPointer.InsertTextElement validates, via ValidationHelper.ValidateChild and an explicit Parent check, that the TextElement being inserted is new (unparented). If textElement.Parent != null — the element already belongs to another tree (or another position in this one) — it throws InvalidOperationException(SR.TextPointer_CannotInsertTextElementBecauseItBelongsToAnotherTree). A TextElement can live in exactly one tree.
Solutions
- Ensure the element is detached first (remove it from its current parent/collection) before inserting.
- Create a new element instance (or deep copy) rather than reusing the parented one.
- If moving between documents, use TextRange/clipboard-based copy APIs or manually reparent: sourceCollection.Remove(element) then target InsertTextElement.
Example fix
// before targetPointer.InsertTextElement(run); // run.Parent != null // after if (run.Parent is TextElementCollection<Run> col) col.Remove(run); ((IAddChild)run.Parent)?. // or: run.RepositionWithContent(null); // detach, then targetPointer.InsertTextElement(run);
Defensive patterns
Strategy: validation
Validate before calling
if (textElement.Parent != null)
{
// detach first
if (textElement.Parent is TextElement p) /* remove from p */;
else if (textElement.Parent is IAddChild) /* remove from container collection */;
} Type guard
bool CanInsert(TextElement e) => e != null && e.Parent == null;
Try / catch
try { pointer.InsertTextElement(element); }
catch (InvalidOperationException ex) when (ex.Message.Contains("another tree")) { /* clone or detach and retry */ } Prevention
- Always Remove an element from its current collection before reinserting
- Deep-copy elements when moving content between documents
- Never cache and reuse parented TextElement instances
When it happens
Trigger: Calling InsertTextElement (via TextPointer.Insert, TextElementCollection.Add/Insert, InsertEmbeddedObject/UIElement wrappers, or InsertLineBreak-style helpers) with an element instance that is already parented — e.g. re-inserting a Run/UIElement that was removed from one document into another, or moving an element without detaching it.
Common situations: Moving a Run or embedded UIElement from one FlowDocument/RichTextBox to another; caching element instances and reusing them after the document was reloaded; cloning documents by reusing child elements instead of deep-copying.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- " }} " element found. Expected fixed page element ( }} ).
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
- ' ' cannot contain the path delimiter: ' '.
- ' ' cannot start with the reserved character range…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/60d99656419155be.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextPointer.cs:1391
/// Throws ArgumentException is textElement is not valid
/// according to flow schema.
/// </exception>
/// <exception cref="InvalidOperationException">
/// Throws InvalidOperationException if textElement cannot be inserted
/// at this position because it belongs to another tree.
/// </exception>
internal void InsertTextElement(TextElement textElement)
{
Invariant.Assert(textElement != null);
_tree.EmptyDeadPositionList();
SyncToTreeGeneration();
ValidationHelper.ValidateChild(this, textElement, nameof(textElement));
if (textElement.Parent != null)
{
throw new InvalidOperationException(SR.TextPointer_CannotInsertTextElementBecauseItBelongsToAnotherTree);
}
textElement.RepositionWithContent(this);
}
/// <summary>
/// Insert a paragraph break at this position by splitting all elements upto its paragraph ancestor.
/// </summary>
/// <returns>
/// When this position has a paragraph parent, this method returns a
/// normalized position in the beginning of a second paragraph.
///
/// Otherwise, if the position is not parented by a paragraph
/// (for special insertion positions such as table row end, BlockUIContainer boundaries, etc),
/// this method creates a paragraph by using rules of EnsureInsertionPosition()
/// and returns a normalized position at the start of the paragraph created.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Throws InvalidOperationException when this position has a non-splittable ancestor such as Hyperlink,View on GitHub (pinned to 81131a70a4)