facebook/react · error · Error
Cannot assign to a client module from a server module.
Error message
Cannot assign to a client module from a server module.
What it means
The set trap of the deep proxy covering nested client references: client references are opaque read-only handles, so mutating an export of a client module from server code throws instead of silently writing into client scope the server cannot see.
Source
Thrown at packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js:204
// 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':
return target.$$async;
case 'name':
return target.name;
// We need to special case this because createElement reads it if we pass this
// reference.
case 'defaultProps':
return undefined;View on GitHub (pinned to eafeac097b)
Solutions
- Move the mutation into client code (an event handler, effect, or module init inside the 'use client' file)
- If it is configuration, pass it as props/arguments to the client component instead of assigning
- Keep mutable shared state in a proper store both sides import by value/props
Example fix
// before (server module)
import * as Editor from './editor-client';
Editor.config.plugins = [myPlugin]; // Error: cannot assign
// after (client component)
'use client';
import {config} from './editor-client';
function EditorHost({plugin}) {
useEffect(() => { config.plugins = [plugin]; }, [plugin]);
return <Editor />;
} Defensive patterns
Strategy: type-guard
Type guard
const CLIENT_REFERENCE = Symbol.for('react.client.reference');
function isClientReference(value) {
return value != null && (typeof value === 'object' || typeof value === 'function') && value.$$typeof === CLIENT_REFERENCE;
}
// guard any configure() helper:
function configure(target, props) {
if (isClientReference(target)) {
throw new Error('Configure client modules from client code, via props');
}
Object.assign(target, props);
} Prevention
- Do all mutation of client-module exports inside 'use client' code
- Pass configuration as props or arguments
- Keep setup/config files side-aware
When it happens
Trigger: `const chart = ClientModule.Chart; chart.theme = 'dark';` — assigning a property on a reference obtained by dotting into a 'use client' module from server code.
Common situations: Monkey-patching a client helper from a server module; shared code that configures libraries imported across the boundary; decorators applied to client exports.
Related errors
- Cannot await or return from a thenable. You cannot await a c
- Cannot access ${expression} on the server. You cannot dot in
- Attempted to call ${String(name)}() from the server but ${St
- 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/53b0b12eb8e7b937.
Report an issue: GitHub.