dotnet/wpf · error · InvalidOperationException

SR.ArrangeReentrancyInvalid

Error message

SR.ArrangeReentrancyInvalid

What it means

Same reentrancy guard as MeasureReentrancyInvalid, but for the arrange phase: VerifyReentrancy throws InvalidOperationException(SR.ArrangeReentrancyInvalid) when a public TextFlow method is called while Flags.ArrangeInProgress is set. TextFlow forbids any public API entry during arrange.

Solutions

  1. Defer the TextFlow call until after arrange completes (Dispatcher.BeginInvoke at Background priority).
  2. Perform document/position changes before initiating layout, not inside ArrangeOverride.
  3. Queue invalidation (InvalidateMeasure/InvalidateArrange) rather than calling TextFlow directly during arrange.

Example fix

// before
protected override Size ArrangeOverride(Size finalSize) {
    _textFlow.SetTextContainerDefaults(...); // reentrancy
    return base.ArrangeOverride(finalSize);
}
// after
protected override Size ArrangeOverride(Size finalSize) {
    Dispatcher.BeginInvoke(() => _textFlow.SetTextContainerDefaults(...));
    return base.ArrangeOverride(finalSize);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot pre-check private flags; avoid TextFlow calls inside ArrangeOverride.

Try / catch

try { DoTextFlowWork(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("arrange")) { Dispatcher.BeginInvoke(DoTextFlowWork); }

Prevention

When it happens

Trigger: Calling any public TextFlow method from ArrangeOverride, from ArrangeCore overrides, or from callbacks raised synchronously during arrange (e.g. property invalidation handlers triggered mid-arrange).

Common situations: Custom panels/text hosts that adjust text layout inside OnArrange/ArrangeOverride; handlers that mutate the document or query positions in response to size changes computed during arrange.

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/240f516a8975bceb. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextFlow.cs:1515

            if (uiChild != null)
            {
                OnChildUIElementChanged(uiChild);
            }
        }

        // ------------------------------------------------------------------
        // Ensures none of our methods can be called during measure/arrange/content change.
        // ------------------------------------------------------------------
        private void VerifyReentrancy()
        {
            if(CheckFlags(Flags.MeasureInProgress))
            {
                throw new InvalidOperationException(SR.MeasureReentrancyInvalid);
            }

            if(CheckFlags(Flags.ArrangeInProgress))
            {
                throw new InvalidOperationException(SR.ArrangeReentrancyInvalid);
            }

            if(CheckFlags(Flags.ContentChangeInProgress))
            {
                throw new InvalidOperationException(SR.TextContainerChangingReentrancyInvalid);
            }
        }

        // ------------------------------------------------------------------
        /// CalculateViewportRect - Called to calculate the visible rect for this element
        // ------------------------------------------------------------------
        private Rect CalculateViewportRect()
        {
            Rect visibleRect = new Rect(0, 0, RenderSize.Width, RenderSize.Height);

            Visual visual = VisualTreeHelper.GetParent(this) as Visual;

            while(visual != null && visibleRect != Rect.Empty)

View on GitHub (pinned to 81131a70a4)