Skip to content

Bug: "Rendered more hooks than ..." throws when it shouldn't with multiple suspends #33556

Open
@Ephem

Description

@Ephem

React version: 19.1.0

I've tried hard to create a minimal reproduction for this one with just React and failed, but for reasons I'll describe I still suspect this might be a React bug and not only a Next.js one.

There are several reproductions over in the Next.js repo: #63121 #63388 #78396 #80483

This one is very, very hard to describe so sorry for a lengthy post. In essence, I think there are situations where transitions changing out a currently pending promise passed to use results in "Rendered too many hooks" being thrown, even when there are no conditional hooks or early returns.

This is not enough however, there seems to be some extra secret ingredient that is required to trigger this which I have not found, maybe incremental hydration?

Why I think this is a bug

This is happening in code paths where there are no conditional hooks being rendered. (Well, there is in the Next case, but it's a NODE_ENV check and the bug happens even when that is removed)

Besides the Next.js reproductions, which vary in how they trigger the bug, I've also seen this happen on a separate code path in our repo, in user land-code where there are also no conditional hooks or early returns. That code path also has two possible Suspends in the same custom hook. This also uses the Next app router, but unlike the reproductions above, the stack trace does not lead to Next.js internals. This internal bug is very hard to reproduce consistently unfortunately.

Some debugging details

  • I have been debugging #78396 with a local Next.js build
  • The bug is triggered on this line in app-router.tsx, but the actual error seems to stem from this line in useActionQueue (?)
    • return isThenable(state) ? use(state) : state
  • I removed the if (process.env.NODE_ENV !== 'production') { conditional hook case just to be sure
  • I added a few logs to useActionQueue, when the bug triggers this is what has happened:

Image

  • That is, a server action is still pending when a redirect happens
  • The error happen when the redirect fulfills
  • If the server action is removed, bug goes away
  • If I add enough delay for the redirect so the server action has time to finish, the bug goes away, that is, this is fine:

Image

  • I have also added a breakpoint to the error itself inside of updateWorkInProgressHook
    • currentHook exists but does not have a .next
    • workInProgressHook exists but does not have a .next
    • This is the stack trace, from beginWork:

Image

I know this is very fuzzy and I'm sorry I don't have more details, but this is where my React debugging skills runs out and I still wanted to report it as there is some good evidence at least part of this bug lies on the React side of things.

I'm happy to provide whatever more details I can help with.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions