dotnet/wpf · error · InvalidOperationException
SR.TextSchema_CannotInsertContentInThisPosition
Error message
SR.TextSchema_CannotInsertContentInThisPosition
What it means
This public TextPointer insertion API (e.g. FixSchemaAndInsertText / insertion via TextRangeEdit) validates that the content to insert is schema-valid at the position. If the content contains no valid child for the position AND position.Parent is null, the schema cannot be fixed up (there is no element to add children to), so it throws InvalidOperationException(SR.TextSchema_CannotInsertContentInThisPosition).
Solutions
- Ensure the document has at least one Paragraph before inserting (e.g. richTextBox.Document.Blocks.Add(new Paragraph())).
- Wrap content in schema-appropriate elements (Paragraph for text at block positions, Run for text inside paragraphs) before insertion.
- Use higher-level APIs like TextRange.Text or RichTextBox.CaretPosition.InsertTextInRun rather than raw insertion at root positions.
Example fix
// before
richTextBox.Document.ContentStart.InsertTextInRun("hello");
// after
if (richTextBox.Document.Blocks.Count == 0)
richTextBox.Document.Blocks.Add(new Paragraph());
var p = richTextBox.Document.Blocks.FirstBlock as Paragraph;
p.ContentStart.InsertTextInRun("hello"); Defensive patterns
Strategy: validation
Validate before calling
if (richTextBox.Document.Blocks.Count == 0)
richTextBox.Document.Blocks.Add(new Paragraph(new Run(""))); Type guard
static bool CanInsertContent(TextPointer p) => p.Parent != null;
Try / catch
try { pointer.InsertTextInRun(text); }
catch (InvalidOperationException) { EnsureParagraph(); repositionedPointer.InsertTextInRun(text); } Prevention
- Guarantee at least one Paragraph exists before low-level insertions
- Wrap inserted content in schema-correct elements
- Prefer TextRange/Selection APIs over raw pointer insertion at root
When it happens
Trigger: Inserting text/elements at a TextPointer whose Parent is null — e.g. at the bare root of an empty document with content that is not allowed there (like inserting a Run directly at the document root where a Paragraph wrapper is required but cannot be inferred).
Common situations: Inserting plain text at Document.ContentStart of an empty RichTextBox through low-level APIs without a paragraph; inserting schema-incompatible content (tables inside inline content) at root-level positions.
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_ChildTypeIsInvalid…
- Can't Assign to Known Member attributes
- SR.FlowDocumentFormattingReentrancy
- SR.FlowDocumentFormattingReentrancy
- SR.FlowDocumentInvalidContnetChange
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/71fea201d27db782.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextPointer.cs:3548
return symbolType;
}
// Inserts an Inline at the current location, adding contextual
// elements as needed to enforce the schema.
internal void InsertInline(Inline inline)
{
TextPointer position = this;
// Check for hyperlink schema validity first -- we'll throw on an illegal Hyperlink descendent insert.
bool isValidChild = TextSchema.ValidateChild(position, /*childType*/inline.GetType(), false /* throwIfIllegalChild */, true /* throwIfIllegalHyperlinkDescendent */);
// Now, it is safe to assume that !isValidChild will be the case of incomplete content.
if (!isValidChild)
{
if (position.Parent == null)
{
// We should try to fix up the schema by adding elements instead of throwing here.
throw new InvalidOperationException(SR.TextSchema_CannotInsertContentInThisPosition);
}
// Ensure text content.
position = TextRangeEditTables.EnsureInsertionPosition(this);
Invariant.Assert(position.Parent is Run, "EnsureInsertionPosition() must return a position in text content");
Run run = (Run)position.Parent;
if (run.IsEmpty)
{
// Remove the implicit (empty) Run, since we are going to insert an inline at this position.
run.RepositionWithContent(null);
}
else
{
// Position is parented by Run, split formatting elements to prepare for inserting inline at this position.
position = TextRangeEdit.SplitFormattingElement(position, /*keepEmptyFormatting:*/false);
}
View on GitHub (pinned to 81131a70a4)