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
- Wrap inline content in a Block: <FlowDocument><Paragraph><Run>text</Run></Paragraph></FlowDocument>
- Check TextSchema.IsValidChildOfContainer(typeof(FlowDocument), value.GetType()) before calling AddChild
- Use the typed Blocks collection (flowDocument.Blocks.Add(block)) instead of IAddChild so invalid types are caught at compile time
- 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
- In XAML always place inline content inside a Paragraph under FlowDocument
- Use the typed Blocks collection instead of IAddChild
- Validate child types with TextSchema before adding
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
- SR.Animation_ChildMustBeKeyFrame
- SR.Animation_ChildMustBeKeyFrame
- SR.Format(SR.CanOnlyHaveOneChild, this.GetType()…
- SR.Format(SR.MustBeOfType, nameof(value)…
- SR.Format(SR.NonWhiteSpaceInAddText, s)
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)