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
- Map class instances to plain object literals before crossing the boundary ({id: user.id, name: user.name}).
- Call an explicit serialization helper (toJSON(), .lean() for Mongoose, raw query options) at the data layer.
- 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
- Return POJOs from the data layer (raw queries, .lean(), toJSON()).
- Keep a boundary function mapping domain objects to DTOs before JSX.
- Run a DEV-time prop walker that reports the offending prop name.
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.