10000 Bug Report: Nextjs form action `ReferenceError: <variable> is not defined` when large data is accessed · Issue #79608 · vercel/next.js · GitHub
[go: up one dir, main page]

Skip to content

Bug Report: Nextjs form action ReferenceError: <variable> is not defined when large data is accessed #79608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
fahidsarker opened this issue May 25, 2025 · 3 comments · Fixed by #79657
Labels
Form (next/form) Related to the Next.js Forms. Server Actions Related to Server Actions.

Comments

@fahidsarker
Copy link

Link to the code that reproduces this issue

https://github.com/fahidsarker/nextjs-form-action-bug-reproduced

To Reproduce

NextJS server actions inside form behaves strangely whenever a large data is accessed. It appears to not package anything when a large data is passed.

  • Error seems to be due to the allData variable which is an array of 100 elements:
Image
  • When the form is submitted:
Image it throws the `ReferenceError: user is not defined`

However the error is gone if the allData is accessed outside of server-action:

  • allData is not accessed inside the form
Image
  • form submitted with no issues

The weird thing is Nextjs does not give any logical error to detect this, leading to a very bad debug experience (specially on a large codebase).

A minimal code repo is provided based on a real project to reproduce this bug.

Current vs. Expected behavior

Current: Throws the ReferenceError: user is not defined error
Expected: Form submitted or Points the error to allData variable

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.3.0: Thu Jan  2 20:24:24 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6030
  Available memory (MB): 36864
  Available CPU cores: 12
Binaries:
  Node: 23.7.0
  npm: 10.9.2
  Yarn: N/A
  pnpm: 9.10.0
Relevant Packages:
  next: 15.3.2 // Latest available version is detected (15.3.2).
  eslint-config-next: 15.3.2
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.8.3
Next.js Config:
  output: N/A

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

Form (next/form), Server Actions

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

next dev (local), Vercel (Deployed), Other (Deployed), next start (local)

Additional context

No response

@github-actions github-actions bot added Form (next/form) Related to the Next.js Forms. Server Actions Related to Server Actions. labels May 25, 2025
@vanaigr
Copy link
vanaigr commented May 26, 2025

This may be an issue with turbopack. See: #79594
Does the error go away if you remove --turbopack from next dev?

@fahidsarker
Copy link
Author

Does the error go away if you remove --turbopack from next dev?

Nope. It still throws the error

unstubbable added a commit that referenced this issue May 27, 2025
When a server function passes a closure to a method on a closed-over
value (e.g. an array), we must correctly track the value itself so that
it's included in the bound arguments.

For example, in this snippet, `list` must be bound to the server action:

```js
export function Component({ list }) {
  return (
    <form
      action={async () => {
        'use server'
        console.log(list.find((x) => !!x))
      }}
    >
      <button>submit</button>
    </form>
  )
}
```

This use case used to work but was accidentally broken by #73189.

fixes #79608
closes NAR-8
@icyJoseph
Copy link
Contributor
icyJoseph commented May 27, 2025

Hi,

This is a bug with how the closure is captured to be re-used when the action is called. If you add allData, and user to the console.log you do, then it'll work:

          console.log({
            formData,
            myData,
            name,
            email,
            redirUrl,
            // add these two
            allData,
            user,
          });

The team has already prepared a PR to fix the issue.

Though, the workaround you have posted, is the right way to go:

  1. filter the list based on user knowledge during SSR time
  2. the payload sent when submitting the Server Functions contains only the current 8000 user's data

And, even though, the closure data is encrypted, it is good practice to not include unnecessary data client side, even more, if this is potentially sensitive data.

In general, be defensive when passing data from Server to Client boundaries. Include only things that are absolutely necessary.

unstubbable added a commit that referenced this issue May 27, 2025
When a server function passes a closure to a method on a closed-over
value (e.g. an array), we must correctly track the value itself so that
it's included in the bound arguments.

For example, in this snippet, `list` must be bound to the server action:

```js
export function Component({ list }) {
  return (
    <form
      action={async () => {
        'use server'
        console.log(list.find((x) => !!x))
      }}
    >
      <button>submit</button>
    </form>
  )
}
```

This use case used to work but was accidentally broken by #73189.

fixes #79608
fixes #77247
closes NAR-8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Form (next/form) Related to the Next.js Forms. Server Actions Related to Server Actions.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
0