Skip to content

[go_router] Fix pop() restoring stale configuration when route has onExit#11241

Open
dkajiwara wants to merge 2 commits intoflutter:mainfrom
dkajiwara:fix/go-router-pop-restore-redirect
Open

[go_router] Fix pop() restoring stale configuration when route has onExit#11241
dkajiwara wants to merge 2 commits intoflutter:mainfrom
dkajiwara:fix/go-router-pop-restore-redirect

Conversation

@dkajiwara
Copy link

GoRouter.pop() unconditionally called restore() after routerDelegate.pop(). When the route has onExit, the pop is deferred to a microtask, so restore() was called with the pre-pop configuration. This caused async redirects to overwrite
the post-pop state, making the popped route reappear.

Fixed by comparing currentConfiguration identity before and after pop. restore() is only called when the configuration was actually updated (synchronous pop).

Fixes flutter/flutter#174525 flutter/flutter#180002

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

…has onExit

When a route has onExit, _handlePopPageWithRouteMatch defers the pop to
a microtask. Calling restore() immediately with the pre-pop
currentConfiguration can trigger async redirects that overwrite the
eventual pop result.

Detect synchronous completion by comparing currentConfiguration identity
before and after the pop call, avoiding any mutable flag on the delegate.
@dkajiwara dkajiwara requested a review from chunhtai as a code owner March 13, 2026 08:17
@google-cla
Copy link

google-cla bot commented Mar 13, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@github-actions github-actions bot added p: go_router triage-framework Should be looked at in framework triage labels Mar 13, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes an issue where GoRouter.pop() could restore a stale configuration when a route has an onExit handler, which could lead to the popped route reappearing. The fix cleverly uses an identical() check to ensure restore() is only called for synchronous pops where the configuration has actually changed. The changes are well-supported by new regression tests that cover the fixed scenario and related edge cases. My review includes one suggestion to enhance a code comment for better long-term maintainability.

Comment on lines +588 to +589
// Only restore when the pop completed synchronously (no onExit).
// If deferred, currentConfiguration is still the same instance.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current comment explains the condition well. To further improve maintainability, consider adding a brief note about why this check is important, mentioning the risk of restoring a stale configuration. This will help future developers understand the full context and prevent accidental regressions.

// Only restore on a synchronous pop to avoid restoring a stale configuration.
// A deferred pop (e.g. due to an async `onExit`) would leave the
// `currentConfiguration` instance unchanged, and restoring it could cause issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p: go_router triage-framework Should be looked at in framework triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[go_router]: Timing Inconsistency: Generated Routes vs Manual Routes in _handlePopPageWithRouteMatch Due to onExit Callback Behavior

1 participant