dotnet/wpf · error · InvalidOperationException

SR.TextPositionIsFrozen

Error message

SR.TextPositionIsFrozen

What it means

This InvalidOperationException is thrown by DocumentSequenceTextPointer.ITextPointer.MoveByOffset when the text pointer is frozen. Frozen pointers (created with ITextPointer.Freeze) are immutable; any mutation API that would change their position must reject the call. The library throws eagerly rather than silently ignoring the move.

Solutions

  1. Create a mutable clone before moving: call CreatePointer() (or CreateStaticPointer for read-only use) on the frozen pointer and call MoveByOffset on the clone.
  2. Remove the unnecessary Freeze() call if the pointer still needs to be moved.
  3. Guard with pointer.IsFrozen and only move unfrozen pointers.

Example fix

// before
frozenPointer.MoveByOffset(3);
// after
if (!frozenPointer.IsFrozen)
    frozenPointer.MoveByOffset(3);
else
    var movable = frozenPointer.CreatePointer();
    movable.MoveByOffset(3);
Defensive patterns

Strategy: try-catch

Validate before calling

if (pointer == null || pointer.IsFrozen) pointer = pointer?.CreatePointer();

Type guard

bool IsMovable(ITextPointer p) => p is { IsFrozen: false };

Try / catch

try { pointer.MoveByOffset(offset); } catch (InvalidOperationException) { var clone = pointer.CreatePointer(); clone.MoveByOffset(offset); }

Prevention

When it happens

Trigger: Calling MoveByOffset (or MoveToLineBoundary/MoveByCharacter variants that route through it) on a DocumentSequenceTextPointer whose _isFrozen flag is true, i.e. one on which Freeze() was previously called.

Common situations: Sharing a cached pointer across code paths where one consumer froze it; holding a pointer snapshot for comparison/editing detection and then attempting to navigate with it; editor/text-selection code that freezes pointers for stability checks and later reuses them for movement.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/fbe2cac17217a458. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentSequenceTextPointer.cs:453

        #region TextNavigator Methods

        /// <summary>
        /// <see cref="ITextPointer.MoveByOffset"/>
        /// </summary>
        bool ITextPointer.MoveToNextContextPosition(LogicalDirection direction)
        {
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");
            return DocumentSequenceTextPointer.iScan(this, direction);
        }


        /// <summary>
        /// <see cref="ITextPointer.MoveByOffset"/>
        /// </summary>
        int ITextPointer.MoveByOffset(int offset)
        {
            if (_isFrozen) throw new InvalidOperationException(SR.TextPositionIsFrozen);

            if (DocumentSequenceTextPointer.iScan(this, offset))
            {
                return offset;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// <see cref="ITextPointer.MoveToPosition"/>
        /// </summary>
        void ITextPointer.MoveToPosition(ITextPointer position)
        {
            DocumentSequenceTextPointer tp = this.AggregatedContainer.VerifyPosition(position);

View on GitHub (pinned to 81131a70a4)