From 1d163962b21f9396d26930e31719bd8b10d9e107 Mon Sep 17 00:00:00 2001 From: Dennis Kats Date: Sat, 2 Aug 2025 18:11:54 -0400 Subject: [PATCH] Allow returning a temporary reference inside an async function (#33761) ## Summary Fixes `await`-ing and returning temporary references in `async` functions. These two operations invoke `.then()` under the hood if it is available, which currently results in an "Cannot access then on the server. You cannot dot into a temporary client reference..." error. This can easily be reproduced by returning a temporary reference from a server function. Fixes #33534 ## How did you test this change? I added a test in a new test file. I wasn't sure where else to put it. image --- .../ReactFlightServerTemporaryReferences.js | 3 ++ ...actFlightServerTemporaryReferences-test.js | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 packages/react-server/src/__tests__/ReactFlightServerTemporaryReferences-test.js diff --git a/packages/react-server/src/ReactFlightServerTemporaryReferences.js b/packages/react-server/src/ReactFlightServerTemporaryReferences.js index e368b2e800..e28b603edf 100644 --- a/packages/react-server/src/ReactFlightServerTemporaryReferences.js +++ b/packages/react-server/src/ReactFlightServerTemporaryReferences.js @@ -70,6 +70,9 @@ const proxyHandlers = { `Instead, you can export a Client Component wrapper ` + `that itself renders a Client Context Provider.`, ); + // Allow returning a temporary reference from an async function + case 'then': + return undefined; } throw new Error( // eslint-disable-next-line react-internal/safe-string-coercion diff --git a/packages/react-server/src/__tests__/ReactFlightServerTemporaryReferences-test.js b/packages/react-server/src/__tests__/ReactFlightServerTemporaryReferences-test.js new file mode 100644 index 0000000000..7e93179268 --- /dev/null +++ b/packages/react-server/src/__tests__/ReactFlightServerTemporaryReferences-test.js @@ -0,0 +1,36 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + * @jest-environment node + */ + +'use strict'; + +let ReactFlightServerTemporaryReferences; + +describe('ReactFlightServerTemporaryReferences', () => { + beforeEach(() => { + jest.resetModules(); + ReactFlightServerTemporaryReferences = require('react-server/src/ReactFlightServerTemporaryReferences'); + }); + + it('can return a temporary reference from an async function', async () => { + const temporaryReferenceSet = + ReactFlightServerTemporaryReferences.createTemporaryReferenceSet(); + const temporaryReference = + ReactFlightServerTemporaryReferences.createTemporaryReference( + temporaryReferenceSet, + 'test', + ); + + async function foo() { + return temporaryReference; + } + + await expect(foo()).resolves.toBe(temporaryReference); + }); +});