dotnet/wpf · error · InvalidOperationException
SR.TextSchema_ChildTypeIsInvalid (parent type name…
Error message
SR.TextSchema_ChildTypeIsInvalid (parent type name, childType.Name)
What it means
Overload of ValidateChild taking (TextElement parent, Type childType, ...) that validates a prospective child TYPE against the parent element. If childType is not a valid child of parent.GetType() per the text schema and throwIfIllegalChild is true, an InvalidOperationException naming the parent type and the child type is thrown. Used by APIs that plan insertions before an element exists.
Solutions
- Call TextSchema.IsValidChild(parent, childType) before attempting the insertion
- Choose a schema-legal childType for the parent (Inline types under Span/Paragraph; Block types under FlowDocument/Section/TableCell)
- Insert an intermediate container that makes the pair legal (e.g. wrap a Run in a Paragraph when a Block parent needs content)
- Catch InvalidOperationException, parse parent/child names from the message, and correct the document structure
Example fix
// before
if (span.Inlines.CanAdd(typeof(Paragraph))) { } // never valid; ValidateChild throws
// after
if (TextSchema.IsValidChild(span, typeof(Inline)))
{
span.Inlines.Add(new Run("text"));
} Defensive patterns
Strategy: validation
Validate before calling
if (!TextSchema.IsValidChild(parent, childType)) { /* choose another childType or restructure */ } Type guard
static bool IsLegalChildType(TextElement parent, Type childType) => TextSchema.IsValidChild(parent.GetType(), childType);
Try / catch
try { DoPlannedInsertion(parent, childType); } catch (InvalidOperationException ex) when (ex.Message.Contains("ChildTypeIsInvalid")) { FallbackToDefaultChildType(parent); } Prevention
- Probe with IsValidChild(parent, childType) before planning insertions
- Use throwIfIllegalChild:false when merely probing schema legality
- Map parent types to legal child types in a helper table
When it happens
Trigger: Calling validation-driven insertion APIs with a childType illegal for the parent, e.g. checking/adding typeof(Paragraph) as child of a Span, typeof(Run) as child of FlowDocument, or typeof(Table) under a Hyperlink, during TextRange edit planning (CreateImplicitRun / split operations).
Common situations: Programmatic FlowDocument construction with wrong nesting; framework-internal text edits (splitting runs, converting elements) hitting positions where the schema forbids the child type.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- SR.TextSchema_ChildTypeIsInvalid (parent type name, child…
- SR.TableCollectionInOtherCollection
- SR.TextSchema_IllegalHyperlinkChild (childType)
- " }} " element found. Expected fixed page element ( }} ).
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5418699ef75fe3a1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextSchema.cs:144
// Disallow nested hyperlink elements.
if (TextSchema.HasHyperlinkAncestor(parent))
{
if (typeof(Hyperlink).IsAssignableFrom(childType) ||
typeof(AnchoredBlock).IsAssignableFrom(childType))
{
if (throwIfIllegalHyperlinkDescendent)
{
throw new InvalidOperationException(SR.Format(SR.TextSchema_IllegalHyperlinkChild, childType));
}
return false;
}
}
bool isValidChild = IsValidChild(parent.GetType(), childType);
if (!isValidChild && throwIfIllegalChild)
{
throw new InvalidOperationException(SR.Format(SR.TextSchema_ChildTypeIsInvalid, parent.GetType().Name, childType.Name));
}
return isValidChild;
}
internal static bool IsValidChild(TextPointer position, Type childType)
{
return ValidateChild(position, childType, false /* throwIfIllegalChild */, false /* throwIfIllegalHyperlinkDescendent */);
}
internal static bool ValidateChild(TextPointer position, Type childType, bool throwIfIllegalChild, bool throwIfIllegalHyperlinkDescendent)
{
DependencyObject parent = position.Parent;
if (parent == null)
{
TextElement leftElement = position.GetAdjacentElementFromOuterPosition(LogicalDirection.Backward);
TextElement rightElement = position.GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);View on GitHub (pinned to 81131a70a4)