facebook/react · error · Error

Cannot read Symbol exports. Only named exports are supported

Error message

Cannot read Symbol exports. Only named exports are supported on a client module imported on the server.

What it means

Client module proxies serialize references as 'moduleId#exportName' strings, so only string-named exports can cross the server boundary. Reading a symbol-keyed property (any symbol other than the whitelisted Symbol.toPrimitive/Symbol.toStringTag) from a 'use client' module namespace on the server throws — there is no serializable name for the reference.

Source

Thrown at packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js:291

          function then(resolve, reject: any) {
            // Expose to React.
            return Promise.resolve(resolve(proxy));
          } as any,
          // If this is not used as a Promise but is treated as a reference to a `.then`
          // export then we should treat it as a reference to that name.
          target.$$id + '#then',
          false,
        ));
        return then;
      } else {
        // Since typeof .then === 'function' is a feature test we'd continue recursing
        // indefinitely if we return a function. Instead, we return an object reference
        // if we check further.
        return undefined;
      }
  }
  if (typeof name === 'symbol') {
    throw new Error(
      'Cannot read Symbol exports. Only named exports are supported on a client module ' +
        'imported on the server.',
    );
  }
  let cachedReference = target[name];
  if (!cachedReference) {
    const reference: ClientReference<any> = registerClientReferenceImpl(
      function () {
        throw new Error(
          // eslint-disable-next-line react-internal/safe-string-coercion
          `Attempted to call ${String(name)}() from the server but ${String(name)} is on the client. ` +
            `It's not possible to invoke a client function from the server, it can ` +
            `only be rendered as a Component or passed to props of a Client Component.`,
        );
      } as any,
      target.$$id + '#' + name,
      target.$$async,
    );

View on GitHub (pinned to eafeac097b)

Solutions

  1. Import only the specific string-named exports you need instead of reflecting over the namespace
  2. Keep symbol-keyed APIs in shared (non-'use client') modules that the server imports directly
  3. Build a plain object on the server containing just the exports you need and hand that to reflective code

Example fix

// before
import * as clientMod from './client'; // 'use client'
const iter = clientMod[Symbol.iterator]; // symbol read -> throws

// after
import {items} from './client'; // named string export
const iter = items[Symbol.iterator];
Defensive patterns

Strategy: validation

Validate before calling

function readExport(mod, key) {
  if (typeof key === 'symbol' && isClientReference(mod)) {
    // Symbol exports cannot cross the RSC boundary.
    return undefined;
  }
  return mod[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
  );
}

Prevention

When it happens

Trigger: clientMod[Symbol.iterator], mod[customSymbol], or Object.getOwnPropertySymbols(mod) followed by reads, executed against a 'use client' namespace in server code. Dependency-injection containers, iterable protocols, or test mock walkers probing modules by symbol.

Common situations: Reflective libraries (DI containers, registries, iterable helpers) touching client-module namespaces; spreading or destructuring that consults symbol keys; mixing import * as namespaces of client modules into meta-programming code.

Related errors


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