dotnet/wpf · error · InvalidOperationException
SR.DocumentReadOnly
Error message
SR.DocumentReadOnly
What it means
DocumentSequenceTextPointer wraps a read-only document sequence, so the ITextPointer.InsertTextInRun implementation unconditionally throws InvalidOperationException with SR.DocumentReadOnly. FixedDocumentSequence content cannot be edited in place.
Solutions
- Do not edit DocumentSequence content via text pointers; the document is immutable
- Edit the underlying source documents (e.g., individual FlowDocuments) before generating the sequence
- Catch InvalidOperationException and treat the sequence as read-only in the UI (disable editing affordances)
Example fix
// before
ptr.InsertTextInRun("text"); // throws on FixedDocumentSequence
// after
if (ptr is DocumentSequenceTextPointer) { /* sequence is read-only; edit source document instead */ }
else { ptr.InsertTextInRun("text"); } Defensive patterns
Strategy: type-guard
Validate before calling
if (pointer is DocumentSequenceTextPointer)
throw new InvalidOperationException("Document sequence is read-only; InsertTextInRun is not allowed"); Type guard
bool IsEditablePointer(ITextPointer p) => p is not DocumentSequenceTextPointer;
Try / catch
try { ptr.InsertTextInRun(text); }
catch (InvalidOperationException ex) when (ex.Message.Contains("read-only")) { /* disable editing UI */ } Prevention
- Disable editing commands when the viewer shows a FixedDocumentSequence/XPS
- Edit source FlowDocuments instead of the composed sequence
- Check pointer type before calling mutation APIs
When it happens
Trigger: Calling ITextPointer.InsertTextInRun on a pointer obtained from a FixedDocumentSequence/DocumentSequenceTextContainer, typically from text editing or IME composition code.
Common situations: Attempting programmatic text insertion into an XPS/FixedDocumentSequence view; TextEditor pipelines treating the sequence container as editable like a FlowDocument.
Related errors
- SR.FixedDocumentReadonly
- 0x80040209
- args
- Cannot remove signature from read-only file.
- Cannot sign read-only file.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/60042acde7354582.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentSequenceTextPointer.cs:226
}
/// <summary>
/// <see cref="ITextPointer.GetFrozenPointer"/>
/// </summary>
ITextPointer ITextPointer.GetFrozenPointer(LogicalDirection logicalDirection)
{
return TextPointerBase.GetFrozenPointer(this, logicalDirection);
}
/// <summary>
/// Inserts text at a specified position.
/// </summary>
/// <param name="textData">
/// Text to insert.
/// </param>
void ITextPointer.InsertTextInRun(string textData)
{
throw new InvalidOperationException(SR.DocumentReadOnly);
}
/// <summary>
/// Removes content covered by a pair of positions.
/// </summary>
/// <param name="limit">
/// Position following the last symbol to delete. endPosition must be
/// scoped by the same text element as startPosition.
/// </param>
void ITextPointer.DeleteContentToPosition(ITextPointer limit)
{
throw new InvalidOperationException(SR.DocumentReadOnly);
}
// Candidate for replacing MoveToNextContextPosition for immutable TextPointer model
ITextPointer ITextPointer.GetNextContextPosition(LogicalDirection direction)
{
ITextPointer pointer = ((ITextPointer)this).CreatePointer();View on GitHub (pinned to 81131a70a4)