facebook/react · error · Error
Cannot access ${expression} on the server. You cannot dot in
Error message
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. What it means
Named exports of a 'use client' module are server-side Proxies (deepProxyHandlers) that expose only a whitelist: Flight metadata ($$typeof/$$id/$$async/name), displayName/defaultProps/_debugInfo/toJSON returning undefined, Symbol.toPrimitive/Symbol.toStringTag, and Context.Provider. Reading any other property throws with the exact 'Name.prop' expression, because the property's value would only exist in the browser where the module actually runs.
Source
Thrown at packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js:197
// $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 {
switch (name) {
// These names are read by the Flight runtime if you end up using the exports object.
case '$$typeof':
return target.$$typeof;
case '$$id':
return target.$$id;
case '$$async':View on GitHub (pinned to eafeac097b)
Solutions
- Import the deeper name directly: import {Chart} from './charts' instead of import * as Charts plus Charts.Chart.COLORS
- Expose what you need as additional named exports of the client module and import those
- Move shared constants/objects out of the 'use client' file into a directive-free shared module
- Do not pass client references to HOC or statics-reading utilities on the server
Example fix
// before (server component)
import * as Charts from './charts'; // 'use client'
const COLORS = Charts.Chart.COLORS; // dots into a client export -> throws
// after
// colors.js (no 'use client'): export const COLORS = [...]
import {COLORS} from './colors';
import {Chart} from './charts'; Defensive patterns
Strategy: type-guard
Validate before calling
function safeRead(obj, key) {
if (isClientReference(obj)) {
// Only metadata and component usage are allowed; do not dot into it.
return undefined;
}
return obj[key];
} 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 {
value = clientExport.prop;
} catch (e) {
if (String(e.message).includes('on the server') && String(e.message).includes('Cannot access')) {
value = undefined; // pass the reference through instead of reading into it
} else {
throw e;
}
} Prevention
- Import the exact named export you need instead of dotting into namespaces of client modules
- Keep constants and config objects in directive-free shared modules
- Do not pass client references to HOCs or utilities that read arbitrary statics on the server
When it happens
Trigger: Dotting into a client export instead of importing the deeper name: Charts.Chart.COLORS, Icon.paths, Button.metadata. HOC, prop-type, or statics-reading machinery touching non-whitelisted properties of a client component reference. Debug tooling or console expansion that evaluates getters on the proxy.
Common situations: Component libraries re-exported through 'use client' barrels whose config objects or sub-objects are read by wrapper code; namespace-style access (import * as X then X.export.prop); devtools inspection of client references during SSR debugging.
Related errors
- Cannot assign to a client module from a server module.
- Cannot access ${expression} on the server. You cannot dot in
- Cannot access ${expression} on the server. You cannot dot in
- Attempted to call the default export of ${url} from the serv
- Attempted to call ${name}() from the server but ${name} is o
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/e643e743ae404f45.
Report an issue: GitHub.