facebook/react · error · Error
Cannot await or return from a thenable. You cannot await a c
Error message
Cannot await or return from a thenable. You cannot await a client module from a server component.
What it means
In React Server Components, each named export of a 'use client' module is wrapped on the server by deepProxyHandlers, an opaque Proxy. Reading the '.then' property of that proxy — which is exactly what await, return-from-async, Promise.resolve(), or use() do to detect thenables — throws, because resolving the thenable would require the real client-side value, which never loads on the server. Client references may only be rendered as components or forwarded as props.
Source
Thrown at packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js:190
// React looks for debugInfo on thenables.
case '_debugInfo':
return undefined;
// Avoid this attempting to be serialized.
case 'toJSON':
return undefined;
case Symbol.toPrimitive:
// $FlowFixMe[prop-missing]
return Object.prototype[Symbol.toPrimitive];
case Symbol.toStringTag:
// $FlowFixMe[prop-missing]
return Object.prototype[Symbol.toStringTag];
case 'Provider':
// Context.Provider === Context in React, so return the same reference.
// This allows server components to render <ClientContext.Provider>
// which will be serialized and executed on the client.
return receiver;
case 'then':
throw new Error(
`Cannot await or return from a thenable. ` +
`You cannot await a client module from a server component.`,
);
}
// eslint-disable-next-line react-internal/safe-string-coercion
const expression = String(target.name) + '.' + String(name);
throw new Error(
`Cannot access ${expression} on the server. ` +
'You cannot dot into a client module from a server component. ' +
'You can only pass the imported name through.',
);
},
set: function () {
throw new Error('Cannot assign to a client module from a server module.');
},
};
function getReference(target: Function, name: string | symbol): $FlowFixMe {View on GitHub (pinned to eafeac097b)
Solutions
- Replace the dynamic import with a static import and pass the named export through: import {Chart} from './charts', then render <Chart/> or send it as a prop
- If the awaited logic must run on the server, move it into a module without the 'use client' directive
- If the module must load only in the browser, move the dynamic import inside a 'use client' component (e.g. next/dynamic with ssr:false there)
- For helpers that await unknown values, branch on client references first and forward them instead of awaiting
Example fix
// before (server component)
const { Chart } = await import('./charts'); // reads .then on client proxy -> throws
// after (server component)
import { Chart } from './charts'; // 'use client' module, used by reference only
export default function Page() {
return <Chart data={...} />;
} Defensive patterns
Strategy: type-guard
Validate before calling
const CLIENT_REFERENCE_TAG = Symbol.for('react.client.reference');
// Run before awaiting any unknown value in server code:
if (isClientReference(value)) {
// Never await it — render it or pass it through as a prop.
return <Child mod={value} />;
}
const resolved = await value; Type guard
const CLIENT_REFERENCE_TAG = Symbol.for('react.client.reference');
function isClientReference(value) {
return (
value !== null &&
(typeof value === 'object' || typeof value === 'function') &&
value.$$typeof === CLIENT_REFERENCE_TAG
);
} Try / catch
try {
result = await maybeClientRef;
} catch (e) {
if (String(e.message).includes('Cannot await or return from a thenable')) {
// Forward the reference instead of resolving it.
return <ClientComponent mod={maybeClientRef} />;
}
throw e;
} Prevention
- Never dynamic-import or await 'use client' modules inside server components — use static imports and pass exports through
- Treat client exports as opaque handles: render or forward, never await, call, or inspect them
- Keep data fetching in server components; keep browser-only lazy loading inside client components
When it happens
Trigger: Awaiting a named export of a client module in a server component: const {Chart} = await import('./charts'), await Chart, or Chart.then(...). Passing the export to Promise.resolve(Chart), use(Chart), or any 'value-or-promise' helper that probes typeof value.then === 'function'. Returning the client export from an async server component.
Common situations: Client-style lazy loading (dynamic import + await) copied into a server component; SSR-disabled patterns such as next/dynamic with ssr:false attempted inside RSC; generic resolvers that accept either a value or a promise receiving a client reference; React 19 use() given a client module export.
Related errors
- Cannot await or return from a thenable. You cannot await a c
- Attempted to call the default export of ${url} from the serv
- Attempted to call ${name}() from the server but ${name} is o
- Cannot access ${expression} on the server. You cannot dot in
- Cannot assign to a client module from a server module.
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/fd9748b24e4584fa.
Report an issue: GitHub.