dotnet/wpf · error · InvalidOperationException

SR.InvalidOperation_CannotClearFwdStack

Error message

SR.InvalidOperation_CannotClearFwdStack

What it means

Journal.ClearForwardStack() removes all entries after the current position, but refuses to do so while there is an uncommitted forward navigation in progress (_uncommittedCurrentIndex > _currentEntryIndex). WPF throws InvalidOperationException because clearing the forward stack during an uncommitted navigation would corrupt journal indexes.

Solutions

  1. Avoid calling navigation/journal APIs while a navigation is in flight; wait for NavigationService navigation to complete (LoadCompleted/NavigationFailed)
  2. Serialize navigations; do not start a new Navigate before the previous one finishes
  3. Remove explicit AddBackEntry calls that race with normal navigation recording

Example fix

// before
frame.NavigationService.AddBackEntry(myState);
frame.NavigationService.Navigate(page); // races with uncommitted entry
// after
frame.NavigationService.Navigate(page);
frame.NavigationService.LoadCompleted += (s, e) => { /* safe to inspect journal */ };
Defensive patterns

Strategy: validation

Validate before calling

// allow navigation only when idle
bool canNavigate = navService.Content == null || lastNavCompleted;
if (!canNavigate) return; // defer or queue the navigation

Try / catch

try { frame.NavigationService.Navigate(uri); }
catch (InvalidOperationException ex) when (ex.Message.Contains("forward stack")) {
    // queue navigation until current one completes
}

Prevention

When it happens

Trigger: RecordNewNavigation processing a navigation while an earlier uncommitted navigation left _uncommittedCurrentIndex ahead of _currentEntryIndex; interleaving AddBackEntry/navigation calls such that a new navigation is recorded before the previous one committed.

Common situations: Calling AddBackEntry or manipulating navigation during an in-flight Navigate; hosting frames with rapid programmatic navigation; navigation reentrancy from Navigating event handlers.

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/9971ed08a91adc6a. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/Journal.cs:327

            _uncommittedCurrentIndex = _currentEntryIndex;

            if (!ClearForwardStack())
            {
                // If ClearForwardStack() didn't change the journal, UpdateView() needs to be
                // called here to enable the Back button.
                UpdateView();
            }
        }

        internal bool ClearForwardStack()
        {
            Debug.Assert(ValidateIndexes());

            if (_currentEntryIndex >= TotalCount)
                return false; // nothing to do

            if(_uncommittedCurrentIndex > _currentEntryIndex)
                throw new InvalidOperationException(SR.InvalidOperation_CannotClearFwdStack);

            _journalEntryList.RemoveRange(_currentEntryIndex, _journalEntryList.Count - _currentEntryIndex);
            UpdateView();
            return true;
        }

        internal void CommitJournalNavigation(JournalEntry navigated)
        {
            NavigateTo(navigated);
        }

        internal void AbortJournalNavigation()
        {
            _uncommittedCurrentIndex = _currentEntryIndex;
            UpdateView();
        }

        /// <summary>

View on GitHub (pinned to 81131a70a4)