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 around each named client export throws on every assignment. A server module cannot mutate a client module's exports — the mutation would have to execute in the browser where the module's code lives, so React blocks all writes from the server graph.

Source

Thrown at packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.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

  1. Remove the assignment — configure client components via props or context from the server
  2. Move shared mutable state into a module without the 'use client' directive that both sides import
  3. Run any required module patching in client-side code or tests against the client build, never in the server graph

Example fix

// before (server code)
import { store } from './store'; // 'use client'
store.theme = 'dark'; // assignment -> throws

// after (server component passes config down)
// <StoreProvider initialTheme="dark"><App/></StoreProvider>
Defensive patterns

Strategy: validation

Validate before calling

function assertAssignable(target) {
  if (isClientReference(target)) {
    throw new Error('Refusing to assign to a client reference from server code — use props/context instead.');
  }
}
// assertAssignable(Chart); Chart.theme = 'dark';

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
  );
}

Prevention

When it happens

Trigger: Assigning to a named client export from server code: Chart.theme = 'dark', Button.displayName = 'X', Icons.registry = obj. Monkey-patching a client export during SSR; instrumentation or test setup that assigns statics onto imports.

Common situations: HOC/decorator wrappers that assign statics to components; dev instrumentation patching imported modules; attempts to configure a client library from the server by mutating its exports; codemods or hot-reload shims writing into module objects.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/e97245dcb2f1983a. Report an issue: GitHub.