dotnet/wpf · error · InvalidOperationException
SR.TextSchema_IllegalHyperlinkChild (childType)
Error message
SR.TextSchema_IllegalHyperlinkChild (childType)
What it means
ValidateChild rejects child types that may not appear inside a Hyperlink descendant. Hyperlink (an Inline) may not contain AnchoredBlock elements or nested Hyperlinks; when such a childType is requested inside hyperlink content and throwIfIllegalHyperlinkDescendent is true, this exception is thrown. This keeps hyperlink content inline-only.
Solutions
- Place only inline, non-hyperlink content (Run, Span, Italic, Bold, LineBreak) inside a Hyperlink
- Check TextSchema.IsValidChild(hyperlink, childType) before adding; if false, split content outside the link
- Move AnchoredBlock content (Paragraph/Table/List) outside the Hyperlink, linking only the inline run(s)
- Catch InvalidOperationException mentioning TextSchema_IllegalHyperlinkChild and sanitize pasted content to strip nested links/blocks
Example fix
// before
Hyperlink link = new Hyperlink();
link.Inlines.Add(new Paragraph(new Run("click"))); // invalid: AnchoredBlock in Hyperlink
// after
Hyperlink link = new Hyperlink(new Run("click"));
link.NavigateUri = new Uri("https://example.com"); Defensive patterns
Strategy: validation
Validate before calling
static bool CanAddToHyperlink(Type t) => !(typeof(Hyperlink).IsAssignableFrom(t) || typeof(AnchoredBlock).IsAssignableFrom(t)) && TextSchema.IsValidChild(typeof(Hyperlink), t);
Type guard
static bool IsInlineNonBlock(TextElement e) => e is Inline && !(e is Hyperlink) && !(e is AnchoredBlock);
Try / catch
try { hyperlink.Inlines.Add(inline); } catch (InvalidOperationException ex) when (ex.Message.Contains("IllegalHyperlinkChild")) { /* move element outside the link */ } Prevention
- Only put Run/Span-style inline content inside Hyperlink
- Never nest Hyperlink or add Paragraph/Table/List inside a link
- Check IsValidChild before insertion
When it happens
Trigger: Attempting to insert a Hyperlink or an AnchoredBlock (Paragraph, Table, List, Section, Floater, Figure) as a child inside a Hyperlink's content, e.g. hyper.Inlines.Add(new Paragraph(...)) or nested Hyperlink creation, during construction or paste/edit operations.
Common situations: Nesting hyperlinks in rich text editors; pasting formatted HTML with block-level content inside an anchor; code-generated FlowDocuments that place lists/tables inside link text.
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.Format(SR.TextSchema_CannotSplitElement…
- SR.HyperLinkTargetNotFound
- SR.TextSchema_CannotSplitElement (ancestor type name)
- SR.TextSchema_ChildTypeIsInvalid (parent type name, child…
- SR.TextSchema_ChildTypeIsInvalid (parent type name…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/eb390ff2aa5578cf.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextSchema.cs:134
return isValidChild;
}
internal static bool IsValidChild(TextElement parent, Type childType)
{
return ValidateChild(parent, childType, false /* throwIfIllegalChild */, false /* throwIfIllegalHyperlinkDescendent */);
}
internal static bool ValidateChild(TextElement parent, Type childType, bool throwIfIllegalChild, bool throwIfIllegalHyperlinkDescendent)
{
// 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 */);View on GitHub (pinned to 81131a70a4)