Skip to content

[pull] canary from vercel:canary#1032

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

[pull] canary from vercel:canary#1032
pull[bot] merged 8 commits into
code:canaryfrom
vercel:canary

Conversation

@pull

@pull pull Bot commented May 8, 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 : )

bgw and others added 8 commits May 7, 2026 12:38
…mple u128 (#93552)

As usual, `Effect` is way too generic. This code gets a lot simpler if
you can assume that `value` returns a `u128`.
…fetch the action (#93615)

Thread here:
https://vercel.slack.com/archives/C08V7CU57E1/p1778186281862589?thread_ts=1778182852.380899&cid=C08V7CU57E1

Sometimes GitHub can fail to fetch and run an action due to general
infra flakiness. That can cause this workflow to fail-closed, even
though the action itself is designed to fail-open.

![Screenshot 2026-05-07 at
2.03.36 PM.png](https://app.graphite.com/user-attachments/assets/61b749f8-549c-4945-9384-adae58a7fb1d.png)

Reduce the chance that this can fail-closed due to infra flakiness by
setting `continue-on-error`.
## What?

Includes the changes from 16-2.

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: Josh Story <story@hey.com>
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
…93617)

When `unstable_cache` finds a stale entry during the prospective phase of a prerender, it dispatches a foreground revalidation and returns the in-flight promise. The wrapper's `cacheSignal.beginRead` / `endRead` pair was scoped only to the synchronous lookup.`endRead` in the outer `finally` fires the moment the function returns the promise, before the recompute and `cacheNewResult` have completed. The prospective prerender's `cacheSignal` then resolves `cacheReady` while the recompute is still in flight, ending the prospective phase early. Any `'use cache'` invocation rendered after the `unstable_cache` await in the same component never gets reached, so its RDC entry is never populated, and the final prerender phase throws "Unexpected cache miss after cache warming phase during prerendering."

Returning `await pendingRevalidates[invocationKey]` instead of returning the promise directly keeps the wrapper function suspended until the recompute and `cacheNewResult` actually complete. The outer `finally` then runs `endRead` at the right time, the prospective phase keeps waiting, and downstream `'use cache'` invocations are reached and populate the RDC as expected.

Adds a regression test under the `use-cache` suite that exercises an `unstable_cache` await followed by a downstream `'use cache'` component. Without the fix, the test fails consistently under `__NEXT_CACHE_COMPONENTS=true` with the cache-miss-after-warming error.
When a cache tag contains a non-ASCII character (Hebrew, CJK, emoji, …)
it gets written into the internal `x-next-cache-tags` HTTP header on ISR
responses. Node's `validateHeaderValue` rejects any byte outside
`\t\x20-\x7e`, so the response crashes with `ERR_INVALID_CHAR`. On
Vercel deploys stale-if-error masks the 500 from clients, but
revalidation itself keeps failing and the cache stops refreshing for
affected routes.

This change introduces a single `encodeCacheTag` helper and applies it
at every public boundary — `validateTags` (which `cacheTag()`,
`unstable_cache()`, and `fetch` tags all funnel through),
`getImplicitTags` for path-derived tags, and `revalidatePath` /
`revalidateTag` / `updateTag` for invalidation inputs. The encoder
matches runs of out-of-class code units so surrogate pairs reach
`encodeURIComponent` intact, and it is idempotent on already-encoded
`%xx` sequences, so callers can pass either the raw or the encoded form
interchangeably.

PR #93139 already encodes path-derived tags at construction, but it
misses every user-supplied tag entry point and uses a
`decodeURIComponent` round-trip that silently mangles literal `%xx`
characters in tag values. PR #93167 encodes only at the `setHeader`
sites, which leaves storage and invalidation diverging and requires
every new write site to remember the encoding step. The
canonical-form-at-the-boundary approach taken here covers all entry
points and keeps storage, comparison, and the wire in sync.

fixes #93142
closes #93139
closes #93167

Co-authored-by: Swarnava Sengupta <swarnava.sengupta@vercel.com>
Co-authored-by: Or Nakash <ornakash@gmail.com>
Removes the unstable prefix from `unstable_io`. Since this was only
shipped in canaries with the unstable prefix we are going to just remove
it without retaining the unstable prefix simultaneously.
@pull pull Bot locked and limited conversation to collaborators May 8, 2026
@pull pull Bot added the ⤵️ pull label May 8, 2026
@pull pull Bot merged commit 766b7cb into code:canary May 8, 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.

4 participants