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

The deep-proxy get trap on client references only allows a few framework names ($$typeof, $$id, Provider on contexts, symbol protocol hooks). Any other dot-access throws because the server cannot read a value whose implementation lives in client code; client references may only be passed through to client components.

Source

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

  1. Move the needed value to a server/shared module without 'use client'
  2. Pass the whole reference through to a client component and read the property on the client
  3. Split barrel files so server code never imports client barrels

Example fix

// before (server component)
import * as UI from './ui-client';
const version = UI.Chart.version; // Error: cannot dot into a client module

// after
import {CHART_VERSION} from './constants'; // plain server module
// pass <UI.Chart /> through instead of reading its internals
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;
}
function assertPassThrough(value) {
  if (isClientReference(value)) {
    return; // OK: forward as prop / render as component
  }
  return value; // plain server value: safe to read properties
}

Prevention

When it happens

Trigger: `ClientModule.Chart.version`, destructuring `const {theme} = clientModule.styles`, or reading any property of a 'use client' export from server code.

Common situations: Constants/config that happen to live in a 'use client' file; barrel files mixing client components with shared values; server code trying to inspect a client import.

Related errors


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