Skip to content

next/navigation router.push does not fully navigate #83386

@alja-dips

Description

@alja-dips

Link to the code that reproduces this issue

https://github.com/alja-dips/next-bug (Note: This code does not manage to reproduce the issue, but is as close as I get making a minimal example of what our codebase does)

To Reproduce

  1. Run form submission
  2. Form submission calls server actions with data
  3. Server actions use revalidatePath on certain pages to ensure that user navigation to these pages will have fresh data
  4. Upon successful server action calls call router.push
  5. Observe RSC calls in network tab
  6. Nothing happens

Current vs. Expected behavior

Current: User is not redirected to desired page upon call to router.push
Expected: User is redirected to desired page upon call to router.push

Provide environment information

Operating System:
  Platform: linux (WSL/Docker)
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Thu Jun  5 18:30:46 UTC 2025
  Available memory (MB): 15826
  Available CPU cores: 20
Binaries:
  Node: 22.18.0
  npm: 11.5.2
  Yarn: N/A
  pnpm: 10.15.0
Relevant Packages:
  next: 15.5.1-canary.24 // Latest available version is detected (15.5.1-canary.24).
  eslint-config-next: 15.5.0
  react: 19.1.1
  react-dom: 19.1.1
  typescript: 5.9.2
Next.js Config:
  output: standalone

Which area(s) are affected? (Select all that apply)

Not sure, Linking and Navigating

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local)

Additional context

The issue is not reproducible consequently and hence is suspected to be some kind of race condition or intermittent error. I have attempted to create a minimal repo with a setup similar to what we are doing in our corporate project, but this project setup does not manage to reproduce the issue. Because the codebase in which this issue happens is proprietary I am not free to share the code, but will happily share what information I am allowed to in the hopes of tracking down and resolving the issue.

The issue has been seen both in dev, start, and the production docker build.

In our playwright test traces we can see that each attempt to call router.push results in an RSC call to the target path. Each RSC call responds with 200 OK. This RSC call looks something like this:

--- REQUEST ---
Method: GET
Status Code: 200 OK
Request Headers
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US
Connection: keep-alive
Cookie: {AUTH COOKIE REMOVED}
Host: localhost:3000
Referer: {REMOVED}
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.7339.16 Safari/537.36
next-router-state-tree: {REMOVED}
next-url: {TARGET URL}
rsc: 1
sec-ch-ua: "Chromium";v="140", "Not=A?Brand";v="24", "HeadlessChrome";v="140"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

---RESPONSE---
Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/x-component
Date: Wed, 03 Sep 2025 12:02:32 GMT
Keep-Alive: timeout=5
Transfer-Encoding: chunked
Vary: rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch, Accept-Encoding

Unfortunately playwrights traces does not keep the RSC response bodies so we are unable to inspect their contents.

We've attempted to strengthen the push function with retry logic using the code below, but this only results in more rsc calls but no effect.

export function useNewRouter() {
  const router = useRouter();

  return {
    ...router,
    push: (path: string) => {
      const initialurl = window.location.href;

      router.push(path);

      let attempts = 1;
      const interval = setInterval(() => {
        if (window.location.href === initialurl && attempts <= 3) {
          Log.debug(
            `Initial router push failed to change url to "${path}". Trying again.`,
          );
          router.push(path);
          attempts++;
        } else {
          clearInterval(interval);
        }
      }, 2500);
    },
  };
}

The issue has persisted for about a year, so it has been a problem with-/our usage of- next for some time. We've attempted to migrate the code to use a server side redirect(...) call instead and observe similar behavior as it appears these server side redirect calls use the client side router to perform these redirects after the fact, but this I am less sure about.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Linking and NavigatingRelated to Next.js linking (e.g., <Link>) and navigation.locked

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions