dotnet/wpf · error · ArgumentException

SR.Format(SR.TextSchema_TheChildElementBelongsToAnotherTreeA…

Error message

SR.Format(SR.TextSchema_TheChildElementBelongsToAnotherTreeAlready, this.GetType().Name)

What it means

Thrown by TextElementCollection<T>.InsertAfter as an ArgumentException when the item being inserted already has a Parent. WPF text-tree elements may belong to exactly one tree; the collection refuses to re-parent an element that is already attached anywhere.

Solutions

  1. Remove newItem from its current parent first (e.g. call Remove/RemoveAt on the owning collection, or set the property holding it to null) before InsertAfter.
  2. Create a fresh element instance instead of reusing the existing one, copying over properties/content.
  3. Guard the call: only invoke InsertAfter when newItem.Parent is null.

Example fix

// before
paragraph.InsertAfter(anchorRun, cachedRun); // cachedRun.Parent != null
// after
if (cachedRun.Parent is Paragraph owner)
    owner.Inlines.Remove(cachedRun);
paragraph.InsertAfter(anchorRun, cachedRun);
Defensive patterns

Strategy: validation

Validate before calling

if (newItem.Parent == null)
    collection.InsertAfter(previousSibling, newItem);

Type guard

bool CanInsert(TextElementType item) => item is not null && item.Parent is null;

Try / catch

try { collection.InsertAfter(prev, item); }
catch (ArgumentException ex) when (ex.Message.Contains("belongs to another tree")) { /* detach or clone item, retry */ }

Prevention

When it happens

Trigger: Calling InsertAfter(previousSibling, newItem) where newItem.Parent != null, i.e. newItem is already a child of some TextElementCollection or text tree (even a different position in the same tree).

Common situations: Moving a Run/Paragraph between documents without detaching it first; reusing a cached element instance; accidentally inserting the same element twice after loading XAML.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextElementCollection.cs:253

        /// </param>
        /// <param name="newItem">
        /// A TextElement to be inserted into the collection after the previousSibling.
        /// It must be unlinked from a tree before insertion.
        /// </param>
        public void InsertAfter(TextElementType previousSibling, TextElementType newItem)
        {
            ArgumentNullException.ThrowIfNull(previousSibling);

            ArgumentNullException.ThrowIfNull(newItem);

            if (previousSibling.Parent != this.Parent)
            {
                throw new InvalidOperationException(SR.Format(SR.TextElementCollection_PreviousSiblingDoesNotBelongToThisCollection, previousSibling.GetType().Name));
            }

            if (newItem.Parent != null)
            {
                throw new ArgumentException(SR.Format(SR.TextSchema_TheChildElementBelongsToAnotherTreeAlready, this.GetType().Name));
            }

            ValidateChild(newItem);

            this.TextContainer.BeginChange();
            try
            {
                newItem.RepositionWithContent(previousSibling.ElementEnd);
            }
            finally
            {
                this.TextContainer.EndChange();
            }
        }

        /// <summary>
        /// Inserts a TextElement newItem into a collection before a nextSibling TextElement.
        /// </summary>

View on GitHub (pinned to 81131a70a4)