dotnet/wpf · error · InvalidOperationException

SR.InvalidOperation_NoJournal

Error message

SR.InvalidOperation_NoJournal

What it means

Frame.RemoveBackEntry() throws InvalidOperationException when the frame does not own its own journal (_ownJournalScope == null). A Frame only maintains a back/forward stack when it owns a journal (JournalOwnership set to OwnsJournal, or the frame is a top-level navigation host). When the journal is owned by a parent Frame/NavigationWindow or disabled, journal operations on the child frame are unsupported and the library fails fast.

Solutions

  1. Set Frame.JournalOwnership = JournalOwnership.OwnsJournal on the frame so it owns its journal before calling RemoveBackEntry().
  2. Call RemoveBackEntry on the object that actually owns the journal (the parent Frame or NavigationWindow) instead of the child frame.
  3. Check Frame.CanGoBack (or _ownJournalScope via CanGoBack) and JournalOwnership before calling journal APIs.

Example fix

// before
frame.RemoveBackEntry(); // throws: frame uses parent's journal
// after
if (frame.JournalOwnership != JournalOwnership.OwnsJournal)
{
    frame.JournalOwnership = JournalOwnership.OwnsJournal;
}
if (frame.CanGoBack)
{
    frame.RemoveBackEntry();
}
Defensive patterns

Strategy: try-catch

Validate before calling

bool safe = frame.JournalOwnership == JournalOwnership.OwnsJournal && frame.CanGoBack;

Type guard

bool CanRemoveBackEntry(Frame f) => f.JournalOwnership == JournalOwnership.OwnsJournal && f.CanGoBack;

Try / catch

try { frame.RemoveBackEntry(); }
catch (InvalidOperationException) { /* journal owned by parent; delegate to owner or ignore */ }

Prevention

When it happens

Trigger: Calling Frame.RemoveBackEntry() on a frame whose _ownJournalScope is null — i.e. the frame uses Automatic journal ownership and resolved to a parent's journal, or JournalOwnership is set to UsesParentJournal, or navigation/journaling is disabled.

Common situations: Embedding a Frame inside a NavigationWindow or another Frame and trying to prune the child's back stack; setting JournalOwnership=UsesParentJournal then calling journal APIs on the child; calling RemoveBackEntry before the frame has ever navigated with its own journal.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/5cc762b34c18e599. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Frame.cs:846

        /// </summary>
        /// <param name="state"> The custom content state (or view state) to be encapsulated in the
        /// journal entry. If null, IProvideCustomContentState.GetContentState() will be called on
        /// the NavigationWindow.Content or Frame.Content object.
        /// </param>
        public void AddBackEntry(CustomContentState state)
        {
            VerifyAccess();
            _navigationService.AddBackEntry(state);
        }

        /// <summary>
        /// Removes the first JournalEntry from the frame's back stack.
        /// </summary>
        /// <exception cref="InvalidOperationException"> The frame doesn't own a journal. </exception>
        public JournalEntry RemoveBackEntry()
        {
            if (_ownJournalScope == null)
                throw new InvalidOperationException(SR.InvalidOperation_NoJournal);
            return _ownJournalScope.RemoveBackEntry();
        }

        /// <summary>
        /// Navigates to the Uri and downloads the content. Whether the navigation is
        /// performed synchronously or asynchronously depends on the current default navigation behavior.
        /// </summary>
        /// <param name="source">URI of the application or content being navigated to.</param>
        /// <returns>bool indicating whether the navigation was successfully started or not</returns>
        public bool Navigate(Uri source)
        {
            VerifyAccess();
            return _navigationService.Navigate(source);
        }

        //
        //  INavigator.Navigate
        //

View on GitHub (pinned to 81131a70a4)