Skip to content

Passing data to both client & server component result in always async server tree #74793

Open
@kirchoni

Description

@kirchoni

Link to the code that reproduces this issue

https://stackblitz.com/edit/stackblitz-starters-ex8vzvqf?file=app%2Fpage.tsx

To Reproduce

  1. Start the application in development
  2. Observe the code inside page.tsx, components/client.tsx and components/server.tsx.
  3. Note what the children's type of the InternalClientComponent component

Current vs. Expected behavior

  • The children of the InternalClientComponent should be of type: Symbol(React.element) (or Symbol(React.transitional.element) in react-19)
  • However, they are of type Symbol(React.lazy) indicating that they are suspending or awaiting smth, but they are not, they are a simple <button> element.

IMPORTANT NOTES:

  • Not passing the data property to either the ClientComponent or ServerComponent resolves the issue, pointing me that this is mostly related to the data reference, not the components themselves.
  • It is working with next@14
  • If the data is of primitive type, it's also working
  • Not happening during build

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: Ubuntu 20.04.0 LTS Sat Jan 11 2025 21:19:29 GMT+0200 (Eastern European Standard Time)
  Available memory (MB): NaN
  Available CPU cores: 8
Binaries:
  Node: 18.20.3
  npm: 10.2.3
  Yarn: 1.22.19
  pnpm: 8.15.6
Relevant Packages:
  next: 15.2.0-canary.4 // Latest available version is detected (15.2.0-canary.4).
  eslint-config-next: N/A
  react: 19.0.0
  react-dom: 19.0.0
  typescript: 5.2.2
Next.js Config:
  output: N/A

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

create-next-app, Turbopack, Webpack

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

next dev (local)

Additional context

I tested a different combinations of next 14/15 & react 18/19 as well as dev & build commands and with --turbo flag and webpack respectively - the issue is consistently reproducable since next@15.0.0

I suspect that passing once a reference to a variable get's passed to a client component it gets turned to a promise so it can travel through the network, however there are also server component that are incorrectly reading the promise (instead of the original variable) which turns them into an async tree -> thus subsequent client components are receiving async server components regardless if they are suspending or not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    create-next-appRelated to our CLI tool for quickly starting a new Next.js application.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions