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

  1. Place only inline, non-hyperlink content (Run, Span, Italic, Bold, LineBreak) inside a Hyperlink
  2. Check TextSchema.IsValidChild(hyperlink, childType) before adding; if false, split content outside the link
  3. Move AnchoredBlock content (Paragraph/Table/List) outside the Hyperlink, linking only the inline run(s)
  4. 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

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


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)