From b9f6e3e468099e8230d2210f5a35a786380562bc Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 13 Sep 2024 15:06:51 -0600 Subject: [PATCH 1/2] fix: clone response in first handler to prevent race (#70082) This fixes a race where if the body was resolved before the clone operation, it would clone later, resulting in an error being thrown due to the body already being consumed. # Conflicts: # packages/next/src/server/lib/patch-fetch.ts --- packages/next/src/server/lib/patch-fetch.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index 5e1beaf79a8d8..885f1639927b2 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -735,7 +735,14 @@ function createPatchedFetcher( if (pendingRevalidate) { const res: Response = await pendingRevalidate - return res.clone() + const clonedResponse = res.clone() + + return { + body: await clonedResponse.arrayBuffer(), + headers: clonedResponse.headers, + status: clonedResponse.status, + statusText: clonedResponse.statusText, + } } return (staticGenerationStore.pendingRevalidates[cacheKey] = doOriginalFetch(true, cacheReasonOverride).finally(async () => { @@ -757,7 +764,7 @@ function createPatchedFetcher( patched.__nextGetStaticStore = () => staticGenerationAsyncStorage patched._nextOriginalFetch = originFetch - return patched + return patched as PatchedFetcher } // we patch fetch to collect cache information used for From a34777b03f0c876fcab8d563761029ebbd232aea Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 30 Sep 2024 18:35:28 -0700 Subject: [PATCH 2/2] fix backport --- packages/next/src/server/lib/patch-fetch.ts | 23 +++++++++------------ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index 885f1639927b2..3382c3d6526e1 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -735,21 +735,18 @@ function createPatchedFetcher( if (pendingRevalidate) { const res: Response = await pendingRevalidate - const clonedResponse = res.clone() - - return { - body: await clonedResponse.arrayBuffer(), - headers: clonedResponse.headers, - status: clonedResponse.status, - statusText: clonedResponse.statusText, - } + return res.clone() } return (staticGenerationStore.pendingRevalidates[cacheKey] = - doOriginalFetch(true, cacheReasonOverride).finally(async () => { - staticGenerationStore.pendingRevalidates ??= {} - delete staticGenerationStore.pendingRevalidates[cacheKey || ''] - await handleUnlock() - })) + doOriginalFetch(true, cacheReasonOverride) + .then((res) => { + return res.clone() + }) + .finally(async () => { + staticGenerationStore.pendingRevalidates ??= {} + delete staticGenerationStore.pendingRevalidates[cacheKey || ''] + await handleUnlock() + })) } else { return doOriginalFetch(false, cacheReasonOverride).finally( handleUnlock