facebook/react · error · Error
Cannot access on the server. You cannot dot into a client…
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.
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.
- Attempted to call () from the server but is on the client…
- Attempted to call () from the server but is on the client…
- Attempted to call the default export of
- Attempted to call the default export of
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/e643e743ae404f45.
Report an issue: GitHub.
Appendix: 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)