dotnet/wpf · error · InvalidOperationException

SR.NoBackEntry

Error message

SR.NoBackEntry

What it means

JournalNavigationScope.GoBack navigates backward in the WPF journal. It throws InvalidOperationException('no back entry') when CanGoBack is false — the back journal stack is empty, the call is made off the UI thread, or the application has shut down. There is no journal entry to go back to.

Solutions

  1. Check CanGoBack before calling GoBack.
  2. Initialize UI back-button state from CanGoBack and update it on navigation events (Navigated / CanGoBack changed).
  3. Ensure the call executes on the UI thread via Dispatcher.Invoke.
  4. Catch InvalidOperationException defensively when journal state can change concurrently.

Example fix

// before
backButton.Click += (s, e) => journalScope.GoBack();
// after
backButton.Click += (s, e) => { if (journalScope.CanGoBack) journalScope.GoBack(); };
Defensive patterns

Strategy: validation

Validate before calling

if (journalScope.CanGoBack)
    journalScope.GoBack();

Try / catch

try
{
    journalScope.GoBack();
}
catch (InvalidOperationException)
{
    // no back entry; disable back button
}

Prevention

When it happens

Trigger: Calling GoBack() when CanGoBack is false: first page shown (empty back stack), wrong thread, or after shutdown.

Common situations: Browser-chrome-like Back buttons enabled before any navigation occurred; calling GoBack right after navigation completes; calling from worker threads.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/AppModel/JournalNavigationScope.cs:204

                JournalEntry je = Journal.BeginForwardNavigation();
                // If je is null it indicates that we are going going "forward" to the currently
                // displayed page which has no journal entry. The comment in BeginForwardNavigation
                // explains how this can happen.
                if (je == null)
                {
                    _rootNavSvc.StopLoading();
                    return;
                }
                NavigateToEntry(je);
                // NavigateToEntry() should call AbortJournalNavigation() if navigation is canceled.
            }
        }

        public void GoBack()
        {
            // CanGoBack checks the calling thread and InAppShutdown as well
            if (!CanGoBack)
                throw new InvalidOperationException(SR.NoBackEntry);

            if (!_host.GoBackOverride())
            {
                JournalEntry je = Journal.BeginBackNavigation();
                if (je == null) // See comment in GoForwardInternal().
                {
                    _rootNavSvc.StopLoading();
                    return;
                }
                NavigateToEntry(je);
                // NavigateToEntry() should call Journal.AbortJournalNavigation() if navigation is canceled.
            }
        }

        public void AddBackEntry(CustomContentState state)
        {
            _host.VerifyContextAndObjectState();
            _rootNavSvc.AddBackEntry(state);

View on GitHub (pinned to 81131a70a4)