facebook/react · error · Error
Objects are not valid as a React child (found: ${childrenStr
Error message
Objects are not valid as a React child (found: ${childrenString}). If you meant to render a collection of children, use an array instead. What it means
While traversing/mapPing a children collection, React hit a plain object that is not a renderable type (not an element, string, number, etc.). Objects cannot be rendered, and their string form ('[object Object]') would silently render garbage, so React throws and lists the object's keys to help identify it.
Source
Thrown at packages/react/src/ReactChildren.js:334
nextName,
callback,
);
}
} else if (type === 'object') {
if (typeof (children as any).then === 'function') {
return mapIntoArray(
resolveThenable(children as any),
array,
escapedPrefix,
nameSoFar,
callback,
);
}
// eslint-disable-next-line react-internal/safe-string-coercion
const childrenString = String(children as any);
throw new Error(
`Objects are not valid as a React child (found: ${
childrenString === '[object Object]'
? 'object with keys {' +
Object.keys(children as any).join(', ') +
'}'
: childrenString
}). ` +
'If you meant to render a collection of children, use an array ' +
'instead.',
);
}
}
return subtreeCount;
}
type MapFunc = (child: ?React$Node, index: number) => ?ReactNodeList;
View on GitHub (pinned to eafeac097b)
Solutions
- Render a specific property or stringify deliberately: <div>{String(obj)}</div> or JSON.stringify if debugging
- Extract the field you meant: {user.name} instead of {user}
- For collections, render an array of elements with keys (or React.Children utilities) instead of the raw object
Example fix
// before
const user = await fetchUser(); // {name: 'Ada'}
return <li>{user}</li>; // throws: object with keys {name}
// after
return <li>{user.name}</li>; Defensive patterns
Strategy: type-guard
Validate before calling
// Filter children to renderable primitives before rendering const renderable = (v: unknown): boolean => v == null || ['string', 'number', 'boolean'].includes(typeof v) || (typeof v === 'object' && (v.$$typeof !== undefined || Array.isArray(v))); const safeChildren = React.Children.toArray(children).filter(renderable);
Type guard
const isRenderableChild = (v: unknown): boolean => v == null || typeof v === 'string' || typeof v === 'number' || (typeof v === 'object' && !!(v as any).$$typeof); // React element
Prevention
- Always extract the specific field from data objects before interpolating into JSX
- Type children props (React.ReactNode) so object children fail at compile time
- Remember Date/Map/Set/window are objects too — convert explicitly (date.toISOString(), Array.from(map))
When it happens
Trigger: Passing a plain object literal as a child: <div>{{a: 1}}</div>; rendering an API response object directly ({...JSON.parse(body)}); putting a Map/Set/window or class instance in JSX children, which then flows through React.Children.map/mapIntoArray.
Common situations: Rendering data from fetch/axios before extracting a field (data instead of data.title); interpolating an options object into JSX; children computed by a helper that returns an object instead of an element or string.
Related errors
- 31
- 62
- <textarea> can only have at most one child.
- React.Children.only expected to receive a single React eleme
- Using Maps as children is not supported. Use an array of key
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/2b282210c7b74d03.
Report an issue: GitHub.