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

  1. Move the mutation into client code (an event handler, effect, or module init inside the 'use client' file)
  2. If it is configuration, pass it as props/arguments to the client component instead of assigning
  3. 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

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


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