remix
remix copied to clipboard
Fetchers that throw redirects can cause infinite loops when actions also redirect
What version of Remix are you using?
1.11.1
Are all your remix dependencies & dev-dependencies using the same version?
- [X] Yes
Steps to Reproduce
https://github.com/dmarkow/remix-redirect-issue
- Current page (
/) loads data withuseFetcher - The route that fetcher loads from (
/data) can possibly redirect (in my case, to redirect to a login form if necessary) - Post to an action on that page that returns or throws a redirect (in this example, a log out button that clears the session and redirects to
/login) - After that action completes, the loader for the next page (
/login) starts running. But before the redirect actually happens, the fetcher on the previous page (/) reloads as well, triggering another redirect. - Infinite loop, and the next page never loads.
This started in 1.10.0 with the fetcher revalidation updates.

Expected Behavior
If a redirect is already being handled, additional redirects to the same destination should be ignored and not trigger fetcher revalidations.
Actual Behavior
Infinite loop.
Can confirm this behavior exists now and didn't exist in 1.9. Curious why the fetcher.load is triggered after each thrown redirect? For me, the infinite loop happens after a logout, because fetcher.load gets triggered for some reason after logout, then it tries to authenticate the request -- which throws a redirect, which causes fetcher.load to get triggered for some reason, to infinity.
@barbinbrad At least for this specific issue, 1.9.0 worked fine for me. 1.10.0 is where the issue started (when Remix fully switched to the new router).
@barbinbrad At least for this specific issue, 1.9.0 worked fine for me. 1.10.0 is where the issue started (when Remix fully switched to the new router).
You're right. I just tested it. I had switched to ^1.9.0 which didn't actually resolve to 1.9.0 -- but a hard pin got rid of the problem.
I tried playing with the shouldRevalidate function, but it didn't seem like it was getting called. For me the solution was to not throw a redirect in any route that was fetched from the client. Instead returning null from the session check and handling that case. Obviously, it's a crappy solution.
Cleaning up my issues and it looks like this got resolved starting in 1.12.0 (probably the react-router update to 6.8.0).