facebook/react · error · Error

498

498

Error message

Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.%s

What it means

React Server Components can only send plain objects and a fixed set of built-ins (Date, Map, Set, Promise, TypedArrays, arrays, etc.) across the serialization boundary to Client Components. When the serializer meets a value whose prototype is neither Object.prototype nor a directly null-adjacent prototype — i.e. a class instance or a null-prototype object — it throws, because there is no defined wire format for arbitrary classes.

Source

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

      // We treat AsyncIterables as a Fragment and as such we might need to key them.
      return renderAsyncFragment(request, task, value as any, getAsyncIterator);
    }

    // We put the Date check low b/c most of the time Date's will already have been serialized
    // before we process it in this function but when rendering a Date() as a top level it can
    // end up being a Date instance here. This is rare so we deprioritize it by putting it deep
    // in this function
    if (value instanceof Date) {
      return serializeDate(value);
    }

    // Verify that this is a simple plain object.
    const proto = getPrototypeOf(value);
    if (
      proto !== ObjectPrototype &&
      (proto === null || getPrototypeOf(proto) !== null)
    ) {
      throw new Error(
        'Only plain objects, and a few built-ins, can be passed to Client Components ' +
          'from Server Components. Classes or null prototypes are not supported.' +
          describeObjectForErrorMessage(parent, parentPropertyName),
      );
    }
    if (__DEV__) {
      if (objectName(value) !== 'Object') {
        callWithDebugContextInDEV(request, task, () => {
          console.error(
            'Only plain objects can be passed to Client Components from Server Components. ' +
              '%s objects are not supported.%s',
            objectName(value),
            describeObjectForErrorMessage(parent, parentPropertyName),
          );
        });
      } else if (!isSimpleObject(value)) {
        callWithDebugContextInDEV(request, task, () => {
          console.error(

View on GitHub (pinned to eafeac097b)

Solutions

  1. Map class instances to plain object literals before crossing the boundary ({id: user.id, name: user.name}).
  2. Call an explicit serialization helper (toJSON(), .lean() for Mongoose, raw query options) at the data layer.
  3. Pass only the fields needed as props and keep rich objects server-side.

Example fix

// before
<ClientProfile user={userRecord} /> {/* userRecord = new User(...) */}

// after
<ClientProfile user={{id: userRecord.id, name: userRecord.name}} />
Defensive patterns

Strategy: type-guard

Validate before calling

export function assertPlainProps(props: Record<string, unknown>) {
  for (const [k, v] of Object.entries(props)) {
    if (!isPlainObject(v) && !isKnownBuiltIn(v)) {
      throw new Error(`prop ${k} of ${Object.prototype.toString.call(v)} is not RSC-serializable`);
    }
  }
}
function isKnownBuiltIn(v: unknown): boolean {
  return v == null || ['string', 'number', 'boolean', 'bigint'].includes(typeof v)
    || v instanceof Date || v instanceof Map || v instanceof Set || Array.isArray(v)
    || ArrayBuffer.isView(v) || typeof v === 'symbol' || typeof v === 'function';
}

Type guard

export function isPlainObject(v: unknown): v is Record<string, unknown> {
  if (typeof v !== 'object' || v === null) return false;
  return Object.getPrototypeOf(v) === Object.prototype;
}

Prevention

When it happens

Trigger: Passing a class instance (new User(...), a Mongoose document, a Sequelize row, a moment object) as a prop to a 'use client' component; passing Object.create(null) values; ORM results whose rows are model instances spread straight into JSX.

Common situations: Data layers returning rich model objects; domain-entity classes used in server code; utility libraries returning null-prototype objects for safety; migrating a page to RSC while reusing existing prop shapes.

Related errors


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