From 887a419d2f74c791eb3a39efbca29d55fdc10d32 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 30 Sep 2024 18:52:47 -0700 Subject: [PATCH] fix: clone response in first handler to prevent race (#70082) (#70649) 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. backports #70082 --------- Co-authored-by: Wyatt Johnson --- packages/next/src/server/lib/patch-fetch.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index 5e1beaf79a8d8..3382c3d6526e1 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -738,11 +738,15 @@ function createPatchedFetcher( 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 @@ -757,7 +761,7 @@ function createPatchedFetcher( patched.__nextGetStaticStore = () => staticGenerationAsyncStorage patched._nextOriginalFetch = originFetch - return patched + return patched as PatchedFetcher } // we patch fetch to collect cache information used for