diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index b49fb79dd12b..5dea3bc1b8dc 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -938,6 +938,7 @@ describe('ReactFlight', () => { }); }); + // @gate renameElementSymbol it('should emit descriptions of errors in dev', async () => { const ClientErrorBoundary = clientReference(ErrorBoundary); @@ -945,6 +946,21 @@ describe('ReactFlight', () => { throw value; } + function RenderInlined() { + const inlinedElement = { + $$typeof: Symbol.for('react.element'), + type: () => {}, + key: null, + ref: null, + props: {}, + _owner: null, + }; + return inlinedElement; + } + + // We wrap in lazy to ensure the errors throws lazily. + const LazyInlined = React.lazy(async () => ({default: RenderInlined})); + const testCases = ( <> @@ -1010,6 +1026,18 @@ describe('ReactFlight', () => { + +
+ +
+
); diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 0fd4bc2533f6..650b448b80e4 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -99,6 +99,7 @@ import {resolveOwner, setCurrentOwner} from './flight/ReactFlightCurrentOwner'; import { getIteratorFn, REACT_ELEMENT_TYPE, + REACT_LEGACY_ELEMENT_TYPE, REACT_FORWARD_REF_TYPE, REACT_FRAGMENT_TYPE, REACT_LAZY_TYPE, @@ -2004,6 +2005,15 @@ function renderModelDestructive( resolvedModel, ); } + case REACT_LEGACY_ELEMENT_TYPE: { + throw new Error( + 'A React Element from an older version of React was rendered. ' + + 'This is not supported. It can happen if:\n' + + '- Multiple copies of the "react" package is used.\n' + + '- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n' + + '- A compiler tries to "inline" JSX instead of using the runtime.', + ); + } } if (isClientReference(value)) {