vercel / vercel/next.js

Server Action passed as an argument fails when called after navigation

Open
#96,331 2 comments 0 reactions 1 assignee View on GitHub

@icyJoseph is already working on this.

Since Jul 30, 2026.

Server Actions
Dominant language
JavaScript
Stars
142k
Forks
32.5k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/hi-ogawa/reproductions/tree/main/next-rsc-action-argument

To Reproduce

The reproduction includes following two actions that are exclusively accessed through two pages through two client components:

// app/a/actions.ts
'use server'

export async function actionA() {
  return 'ACTION_A_OK'
}

// app/b/actions.ts
'use server'

export async function actionB(action) {
  return `ACTION_B_OK(${await action()})`
}

The idea is that the client component in /a stashes actionA as client state, then after the navigation, the client component in /b triggers actionB(stashedAction). When actionA is called from page /b in that way, it leads to an error like:

⨯ Error: Failed to find Server Action "002e999fb6c51172959666feee27cb3ccda5ce5565". This request might be from an older or newer deployment.
Read more: https://nextjs.org/docs/messages/failed-to-find-server-action
    at ignore-listed frames {
  digest: '370130379@E974'
}
 POST /b 500 in 149ms (next.js: 3ms, application-code: 146ms)

Following is a step-by-step instruction:

  • Run pnpm install and pnpm dev.
  • Open /a and select Save action A. This retains actionA in shared client runtime state.
  • Navigate client-side to /b.
  • Select Run saved action A directly and observe that it succeeds with ACTION_A_OK.
  • Select Run action B with saved action A.
  • Observe an error.

The automated reproduction is available through pnpm test.

Current vs. Expected behavior

Currently, calling actionB(savedActionA) on page B fails while decoding the arguments, before actionB executes. Page B statically reaches actionB, but it does not statically reach the retained actionA reference.

I expected the valid retained reference to be decoded and passed to actionB, producing:

ACTION_B_OK(ACTION_A_OK)

The reproduction includes two controls:

  • Calling retained actionA directly after navigating to page B succeeds, which confirms that the reference remains valid and normal stale-action forwarding works.
  • Calling outerAction(innerAction) on /nested succeeds when the current page statically reaches both route-local action modules, which confirms that passing a server reference as an action argument is supported in that case.
Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:15 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T6041
  Available memory (MB): 49152
  Available CPU cores: 12
Binaries:
  Node: 24.18.0
  npm: 11.16.0
  Yarn: 1.22.22
  pnpm: 11.17.0
Relevant Packages:
  next: 16.3.0-canary.102
  eslint-config-next: N/A
  react: 19.2.3
  react-dom: 19.2.3
  typescript: 5.9.3
Next.js Config:
  output: N/A
Which area(s) are affected? (Select all that apply)

Server Actions

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

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

Additional context

The result was verified with Next.js 16.3.0-canary.102 in all four combinations:

  • Turbopack development;
  • Turbopack production;
  • Webpack development;
  • Webpack production.

Both production server-reference-manifest.json files confirm that actionA has only app/a/page as a worker and actionB has only app/b/page as a worker.

The observed request flow appears to be:

  1. The explicit request header identifies only the outer actionB.
  2. Next.js sees that page B can execute actionB, so it does not forward the request.
  3. decodeReply() then attempts to revive the serialized actionA argument through page B's server module map.
  4. Page B has no worker entry for actionA, so decoding fails before actionB executes.

Related issues #61918 and #63915 covered directly invoking an action after navigation. That case succeeds in this reproduction. Issue #78529 concerns re-exported actions under Turbopack, while this reproduction fails with both Turbopack and Webpack.

The first canary release containing this behavior has not been identified.


Side note: The actual context is that this reproduction was discovered while analyzing Next.js's action internal dispatching mechanism and exploring similar features on Vite rsc plugin. The discussion is found in https://github.com/vitejs/vite-plugin-react/issues/1337

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.