dotnet/wpf · error · InvalidOperationException

SR.TextPositionIsFrozen

Error message

SR.TextPositionIsFrozen

What it means

ITextPointer.MoveByOffset on FixedTextPointer throws InvalidOperationException(SR.TextPositionIsFrozen) when the pointer was created as frozen/static. Frozen pointers are immutable snapshots (e.g. created via CreateStaticPointer) and cannot be moved.

Solutions

  1. Create a dynamic (non-frozen) pointer via CreateDynamicPointer and move that instead.
  2. Clone/duplicate the frozen pointer's position into a mutable pointer before offsetting.
  3. Guard movement code with a check for the pointer's frozen state.
  4. Catch InvalidOperationException and create a movable pointer at the same position.

Example fix

// before
staticPointer.MoveByOffset(5); // throws: frozen
// after
var movable = container.CreateDynamicPointer(staticPointer, LogicalDirection.Forward);
movable.MoveByOffset(5);
Defensive patterns

Strategy: try-catch

Validate before calling

// Guard: only call MoveByOffset on pointers you created as dynamic.
bool isMovable = !(pointer is FixedTextPointer ftp && ftp.IsFrozen);

Type guard

bool IsFrozen(FixedTextPointer p) => p.IsFrozen; // check before mutating

Try / catch

try { pointer.MoveByOffset(offset); }
catch (InvalidOperationException) { var movable = container.CreateDynamicPointer(pointer, LogicalDirection.Forward); movable.MoveByOffset(offset); }

Prevention

When it happens

Trigger: Calling MoveByOffset on a FixedTextPointer obtained from CreateStaticPointer or otherwise flagged _isFrozen — e.g. static pointers from document structure queries.

Common situations: Storing static pointers for later navigation; code that treats all ITextPointers as mutable; passing a frozen pointer into APIs that adjust offsets.

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/30772f01eb20ddd9. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedTextPointer.cs:391

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

            ValidationHelper.VerifyDirection(direction, "direction");
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");

            return _flowPosition.Move(direction);
        }


        /// <summary>
        /// <see cref="ITextPointer.MoveByOffset"/>
        /// </summary>
        int ITextPointer.MoveByOffset(int offset)
        {
            if (_isFrozen) throw new InvalidOperationException(SR.TextPositionIsFrozen);
    
            if (!_flowPosition.Move(offset))
            {
                throw new ArgumentException(SR.BadDistance, nameof(offset));
            }
            else
            {
                return offset;
            }
        }

        /// <summary>
        /// <see cref="ITextPointer.MoveToPosition"/>
        /// </summary>
        void ITextPointer.MoveToPosition(ITextPointer position)
        {
            FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position);

View on GitHub (pinned to 81131a70a4)