next.js
9dbb357d - [backport] Encode the cache item name built by `unstable_cache` (#97313)

Commit
58 days ago
[backport] Encode the cache item name built by `unstable_cache` (#97313) Backports #96936 ("[refactor] Rename `encodeCacheTag` to `encodeHeaderSafe`") and #96937 ("Encode the cache item name built by `unstable_cache`") to `next-16-3`. Fixes #76286. A cache implementation may serialize cache metadata into HTTP request headers, whose values are limited to Latin-1. `unstable_cache` assembles a cache item name from the request URL and the name of the cached callback, and neither part was encoded. When that name holds a character above U+00FF the conversion throws before the request is dispatched, so the read never reaches the cache and the write that follows it fails the same way. Nothing is stored, nothing is found, and the entry falls back to the origin on every render. The reachable case is a non-ASCII query parameter on any dynamic route that calls `unstable_cache`, whether or not the route reads `searchParams`, because `URLSearchParams` returns decoded keys and values while the pathname stays percent-encoded. The rename is folded in because it is the prerequisite: #96937 imports `encodeHeaderSafe` from `server/lib/encode-header-safe`, which the rename creates. It carries no behavior change, the function body is identical apart from the parameter name, and the two were stacked in this same order on canary. ### Verification on this branch Cherry-picked from `1f0cd93b83` and `4286a42e2c` in that order, with no conflicts. `packages/next/src/server/web/spec-extension/unstable-cache.ts` is not byte-identical to canary, because the release branch predates the unrelated `willConsumerServerCache` change and keeps `workStore.isStaticGeneration` at those two call sites. The diff this backport applies to that file is exactly the encoding change and nothing else. Every other source file is byte-identical to canary, and no reference to the old `encodeCacheTag` name remains. Behavioral verification is left to CI on this branch; the change carries the `non-ascii-cache-item-name` end-to-end suite, which exercises a real cache handler. <!-- NEXT_JS_LLM -->
Author
Parents
Loading