Skip to content

[pull] canary from vercel:canary#1047

Merged
pull[bot] merged 3 commits into
code:canaryfrom
vercel:canary
May 14, 2026
Merged

[pull] canary from vercel:canary#1047
pull[bot] merged 3 commits into
code:canaryfrom
vercel:canary

Conversation

@pull

@pull pull Bot commented May 14, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

lubieowoce and others added 3 commits May 14, 2026 16:50
When rendering dynamically for `cachedNavigations`, we do a staged
render so that we can recover a static prefetch from the stream.
However, we weren't delaying params properly because we were missing
`asyncApiPromises` and `fallbackParams` from the store, so dynamic
params would incorrectly resolve in the static stage.

This was masked in the tests, which accidentally had a bunch of `await
setTimeout(300)` delays left in. so components that were meant to test
when params resolve were always resolving in the dynamic stage, because
timeouts are tasky.

I'm not confident in the fix for missing `fallbackParams`, it's
robot-assisted and i'm not very familiar with those bits, but it seems
to work
Reopens #93710 from a branch on this repo so the required deploy test
matrix can run — GitHub Actions doesn't expose secrets to fork PRs, and
those deploy jobs are required checks. All commits and credit carry
forward from the original PR by @elishagreenwald, which built on earlier
attempts by @LiamBoz in #84525 and @claygeo in #92053.

When middleware rewrites a Server Action POST to a page that doesn't
bundle the action, the receiving worker forwards the request to a worker
that does. The forwarded request hits middleware again and gets
rewritten the same way, so the new receiving worker forwards again —
looping until undici's headers timeout (~300s) or memory pressure brings
the server down (#84504). The fix is two related changes on the
forwarding code path. The first is an `!actionWasForwarded` guard in
`action-handler.ts` so a request carrying `x-action-forwarded: 1` is
never forwarded a second time. The second is a new branch in
`createForwardedActionResponse` that copies the
`x-nextjs-action-not-found` header and 404 status onto the originating
response when the forwarded worker can't find the action either; without
it the client would see a generic "unexpected response" error instead of
the `UnrecognizedActionError` that the rest of the framework expects.

The e2e test at `test/e2e/app-dir/action-forward-loop` reproduces the
scenario. A `proxy.ts` rewrites POSTs to `/with-action` so GETs still
render the page normally; the page renders a `<form>` with an inline
server action wrapped in a React error boundary that branches on
`unstable_isUnrecognizedActionError`. The test clicks the button and
waits for `#action-not-found-error`. Without the loop guard the test
times out at 10s, and without the pass-through the boundary catches a
generic error and the assertion fails — so both changes are individually
load-bearing.

This is a short-term fix. The mid-term direction is to remove
server-side action forwarding altogether and have the client dispatch
each Server Action to the route that actually bundles it, which makes
the entire forwarding code path (and this bug surface) unnecessary.
#90549 is the draft exploring that approach.

Fixes #84504

Closes #93710
Closes #84525
Closes #92053

---------

Co-Authored-By: Elisha Greenwald <ejgreenwald@gmail.com>
Co-Authored-By: LiamBoz <thisamazingnow@gmail.com>
Co-Authored-By: kmaclip <kmartclips@proton.me>
…me for the unvalidated boundary (#93770)

The error message previously did not say which parallel route slot
couldn't be validated. Now it poitns to the nearest segment below the
validation boundary. The idea is you go look abive this and figure out
if it is intentional that this segment isn't rendered in the current
context. If so you can ignored the warning (it should ideally not even
be presented as a normal error) but if it is unintentional you
investigate why you aren't SSRing this slot or you mark the slot as
intentionally blocking so it doesn't get validated.
@pull pull Bot locked and limited conversation to collaborators May 14, 2026
@pull pull Bot added the ⤵️ pull label May 14, 2026
@pull pull Bot merged commit e2b0d2e into code:canary May 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants