dotnet/wpf · error · ArgumentException

SR.Format(SR.TextSchema_ChildTypeIsInvalid…

Error message

SR.Format(SR.TextSchema_ChildTypeIsInvalid, _typeofThis.Name, value.GetType().Name)

What it means

FlowDocument implements IAddChild for XAML parsing, and only accepts children that TextSchema says are valid for a FlowDocument container (Block elements such as Paragraph, Section, Table, List). IAddChild.AddChild validates this first and throws ArgumentException with SR.TextSchema_ChildTypeIsInvalid naming the FlowDocument type and the offending child type.

Solutions

  1. Wrap inline content in a Block: <FlowDocument><Paragraph><Run>text</Run></Paragraph></FlowDocument>
  2. Check TextSchema.IsValidChildOfContainer(typeof(FlowDocument), value.GetType()) before calling AddChild
  3. Use the typed Blocks collection (flowDocument.Blocks.Add(block)) instead of IAddChild so invalid types are caught at compile time
  4. Catch ArgumentException and report which child type was rejected

Example fix

// before
flowDocument.Blocks.Add(new Run("hi")); // or AddChild(new Run("hi")) -> ArgumentException
// after
var para = new Paragraph(new Run("hi"));
flowDocument.Blocks.Add(para);
Defensive patterns

Strategy: validation

Validate before calling

if (!System.Windows.Documents.TextSchema.IsValidChildOfContainer(typeof(System.Windows.Documents.FlowDocument), value.GetType()))
    throw new ArgumentException($"{value.GetType().Name} is not a valid FlowDocument child; wrap in a Block (e.g. Paragraph).");

Type guard

bool IsValidFlowDocumentChild(object o) =>
    o is System.Windows.Documents.Block ||
    System.Windows.Documents.TextSchema.IsValidChildOfContainer(typeof(System.Windows.Documents.FlowDocument), o.GetType());

Try / catch

try { ((System.Windows.Markup.IAddChild)doc).AddChild(value); }
catch (ArgumentException ex) { /* log invalid child type */ }

Prevention

When it happens

Trigger: Calling IAddChild.AddChild on a FlowDocument with an object whose type is not a valid child (e.g. Run, Inline, UIElement, string), typically via XAML parsing or code that uses IAddChild directly.

Common situations: XAML mistakes like putting <Run> or raw text directly under <FlowDocument> (must be inside a Paragraph/Block); programmatic AddChild misuse in generated or parsed markup.

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/9b66cf3389a58385. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FlowDocument.cs:1626

        //  IAddChild Members
        //
        //-------------------------------------------------------------------

        #region IAddChild Members

        ///<summary>
        /// Called to Add the object as a Child.
        ///</summary>
        ///<param name="value">
        /// Object to add as a child
        ///</param>
        void IAddChild.AddChild(Object value)
        {
            ArgumentNullException.ThrowIfNull(value);

            if (!TextSchema.IsValidChildOfContainer(/*parentType:*/_typeofThis, /*childType:*/value.GetType()))
            {
                throw new ArgumentException(SR.Format(SR.TextSchema_ChildTypeIsInvalid, _typeofThis.Name, value.GetType().Name));
            }

            // Checking that the element inserted does not have a parent
            if (value is TextElement && ((TextElement)value).Parent != null)
            {
                throw new ArgumentException(SR.Format(SR.TextSchema_TheChildElementBelongsToAnotherTreeAlready, value.GetType().Name));
            }

            if (value is Block)
            {
                TextContainer textContainer = _structuralCache.TextContainer;
                ((Block)value).RepositionWithContent(textContainer.End);
            }
            else
            {
                Invariant.Assert(false); // We do not expect anything except Blocks on top level of a FlowDocument
            }
        }

View on GitHub (pinned to 81131a70a4)