facebook/react · error · Error

376

376

Error message

Only global symbols received from Symbol.for(...) can be passed to Client Components. The symbol Symbol.for(%s) cannot be found among global symbols.%s

What it means

Symbols can only cross the RSC boundary if they are registered global symbols: the server serializes a symbol by its description and the client recreates it with Symbol.for. A symbol created with Symbol('name') is unique to its creation site and can never be found again on the client, so React throws rather than emit a value that would silently mismatch.

Source

Thrown at packages/react-server/src/ReactFlightServer.js:4308

        'Functions cannot be passed directly to Client Components ' +
          'unless you explicitly expose it by marking it with "use server". ' +
          'Or maybe you meant to call this function rather than return it.' +
          describeObjectForErrorMessage(parent, parentPropertyName),
      );
    }
  }

  if (typeof value === 'symbol') {
    const writtenSymbols = request.writtenSymbols;
    const existingId = writtenSymbols.get(value);
    if (existingId !== undefined) {
      return serializeByValueID(existingId);
    }
    // $FlowFixMe[incompatible-type] `description` might be undefined
    const name: string = value.description;

    if (Symbol.for(name) !== value) {
      throw new Error(
        'Only global symbols received from Symbol.for(...) can be passed to Client Components. ' +
          `The symbol Symbol.for(${
            // $FlowFixMe[incompatible-type] `description` might be undefined
            value.description
          }) cannot be found among global symbols.` +
          describeObjectForErrorMessage(parent, parentPropertyName),
      );
    }

    request.pendingChunks++;
    const symbolId = request.nextChunkId++;
    emitSymbolChunk(request, symbolId, name);
    writtenSymbols.set(value, symbolId);
    return serializeByValueID(symbolId);
  }

  if (typeof value === 'bigint') {
    if (enableTaint) {

View on GitHub (pinned to eafeac097b)

Solutions

  1. Create shared symbols with Symbol.for('name') in a module imported by both server and client.
  2. Replace the symbol with a plain string or number if global registry pollution is a concern.
  3. Audit shared constant modules for bare Symbol() usage.

Example fix

// before — constants.ts
export const STATUS = Symbol('status');

// after
export const STATUS = Symbol.for('app.status');
Defensive patterns

Strategy: type-guard

Validate before calling

export function assertGlobalSymbols(props: Record<string, unknown>) {
  for (const [k, v] of Object.entries(props)) {
    if (typeof v === 'symbol' && !isGlobalSymbol(v)) {
      throw new Error(`prop ${k} uses a non-global symbol — use Symbol.for()`);
    }
  }
}

Type guard

export function isGlobalSymbol(v: unknown): v is symbol {
  return typeof v === 'symbol' && v.description != null && Symbol.for(v.description) === v;
}

Prevention

When it happens

Trigger: Passing const KIND = Symbol('kind') as a prop to a client component; exporting symbols created with bare Symbol('...') from modules whose values end up in client props.

Common situations: Enum-like constants defined with Symbol() instead of Symbol.for(); libraries exporting symbol keys used in prop objects; defensive-coding habits that use unique symbols to avoid collisions.

Related errors


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