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

The client module proxy only supports string-named exports; any symbol-keyed lookup throws. Symbols cannot be serialized across the Flight boundary, so rather than pretend to succeed (and loop forever on feature tests), the proxy rejects symbol access.

Source

Thrown at packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.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. Convert data to plain serializable values on the server before passing it across
  2. Do the iteration/spreading inside a client component
  3. When logging or serializing, log a marker (id, name) instead of deep-inspecting the reference

Example fix

// before (server component)
import * as Data from './data-client';
for (const item of Data.items) {...} // reads Symbol.iterator -> Error

// after
// pass Data.items to a client component and iterate there:
// <ItemList items={Data.items} />
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 safeIterate(value) {
  if (isClientReference(value)) {
    throw new Error('Iterate this reference inside a client component instead');
  }
  return value[Symbol.iterator]();
}

Prevention

When it happens

Trigger: Iterating a client export (`for (const x of ClientModule.items)` reads Symbol.iterator), spreading a client reference in server code, or tooling probing symbols (util.inspect, jest/Vitest serializers) on the proxy.

Common situations: Shared utility code that iterates/spreads imports which crossed a 'use client' boundary; test snapshots deep-walking client references; logging frameworks inspecting proxies.

Related errors


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