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
- Avoid calling navigation/journal APIs while a navigation is in flight; wait for NavigationService navigation to complete (LoadCompleted/NavigationFailed)
- Serialize navigations; do not start a new Navigate before the previous one finishes
- 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
- Serialize navigations; wait for LoadCompleted before starting another
- Avoid AddBackEntry during in-flight navigations
- Do not trigger navigation recursively from Navigating handlers
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
- SR.Format(SR.CustomContentStateMustBeSerializable, type)
- SR.Format(SR.InvalidOperation_MustImplementIPCCSOrHandleNavi…
- SR.InvalidOperation_AddBackEntryNoContent
- SR.InvalidOperation_CantChangeJournalOwnership
- SR.InvalidOperation_NoJournal
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)