How to fix Symbols are not valid as React children in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025ยท 101 views

This error occurs when attempting to render a JavaScript Symbol directly in JSX or pass it as a React child. React cannot render Symbols because they are non-serializable primitive types that have no string representation suitable for DOM rendering.

Quick fix

Fixes Symbols are not valid as React children

// WRONG - Symbol cannot be rendered
function MyComponent() {
  const uniqueId = Symbol('id');
  return <div>{uniqueId}</div>; // Error!
}

// WRONG - Symbol in props
function Badge({ icon }) {
  return <span>{icon}</span>;
}
<Badge icon={Symbol('badge')} /> // Error!
  1. Locate the Symbol usage in your JSX
  2. Convert Symbol to string representation if display is needed
  3. Use Symbols for internal logic only, not rendering
  4. Remove Symbol from key props
react โ€” error
// WRONG - Symbol cannot be rendered
function MyComponent() {
const uniqueId = Symbol('id');
return <div>{uniqueId}</div>; // Error!
}
// WRONG - Symbol in props
function Badge({ icon }) {
return <span>{icon}</span>;
}
<Badge icon={Symbol('badge')} /> // Error!
Symbols are not valid as React children

What this error means

This error is thrown by React when you try to use a JavaScript Symbol as a child element in JSX. React's rendering engine only accepts specific types as valid children: strings, numbers, React elements, fragments, portals, booleans, null, and undefined. Symbols are primitive JavaScript types created with Symbol() or Symbol.for() that serve as unique identifiers, but they cannot be serialized or converted to strings for DOM rendering. React's internal reconciliation process expects to work with renderable content or values it can safely skip (like null/undefined/booleans). When it encounters a Symbol, it cannot determine how to represent it in the DOM, leading to this error. This commonly happens when Symbol values leak into component props or JSX expressions, either through direct rendering attempts or when objects containing Symbol properties are accidentally passed to components. The error is a safeguard to prevent runtime failures in the browser, as the DOM API has no way to handle Symbol types as text content or attributes.

Typical symptoms

  • React app crashes with "Symbols are not valid as React children" error message
  • Component renders nothing or shows an error boundary when content should appear
  • Error occurs when using Symbol() or Symbol.for() values in JSX expressions
  • TypeScript may not catch the error if children prop types are too permissive
  • Error appears after refactoring code that uses Symbols for internal keys or identifiers
  • Console shows error pointing to specific JSX element or component
  • Application breaks only when certain data containing Symbols is rendered

Common causes

  1. Directly rendering a Symbol in JSX: {mySymbol} or <div>{Symbol.for("key")}</div>
  2. Passing a Symbol as a prop value that the component attempts to render
  3. Using Symbol as key prop: key={Symbol("uniqueKey")} causes type conversion error
  4. Accidentally spreading an object with Symbol properties into JSX: {...objWithSymbols}
  5. API response or state contains Symbol values that leak into render logic
  6. Third-party library returns Symbol values that are passed to React components
  7. Using Symbol.iterator or other well-known Symbols in places expecting renderable content
  8. Debugging code left in production that renders Symbol values for inspection

How to fix "Symbols are not valid as React children"

1Locate the Symbol usage in your JSX

Check your component's render logic for any direct Symbol references. Look for Symbol() or Symbol.for() calls in JSX expressions:

jsx
// WRONG - Symbol cannot be rendered
function MyComponent() {
  const uniqueId = Symbol('id');
  return <div>{uniqueId}</div>; // Error!
}

// WRONG - Symbol in props
function Badge({ icon }) {
  return <span>{icon}</span>;
}
<Badge icon={Symbol('badge')} /> // Error!

Use your browser console's error stack trace to identify the exact component and line number where the Symbol is being rendered.

2Convert Symbol to string representation if display is needed

If you need to show the Symbol value for debugging or logging purposes, convert it to a string first:

jsx
// CORRECT - Convert to string
function MyComponent() {
  const uniqueId = Symbol('id');
  return <div>{String(uniqueId)}</div>; // Shows "Symbol(id)"
  // or
  return <div>{uniqueId.toString()}</div>;
  // or
  return <div>{uniqueId.description}</div>; // Shows just "id"
}

Use .description property for cleaner output without the "Symbol()" wrapper.

3Use Symbols for internal logic only, not rendering

Refactor your code to keep Symbol values in logic layer and use strings/numbers for UI:

jsx
// CORRECT - Symbol for internal use, string for display
const STATUS_PENDING = Symbol('pending');
const STATUS_COMPLETE = Symbol('complete');

const STATUS_LABELS = {
  [STATUS_PENDING]: 'Pending',
  [STATUS_COMPLETE]: 'Complete'
};

function TaskStatus({ status }) {
  return <div>{STATUS_LABELS[status]}</div>; // Renders string
}

<TaskStatus status={STATUS_PENDING} /> // Works!

This pattern keeps type-safe Symbol constants while rendering human-readable strings.

4Remove Symbol from key props

React keys must be strings or numbers. If you're using Symbol for unique keys, replace with string-based identifiers:

jsx
// WRONG - Cannot convert Symbol to string for key
items.map(item => (
  <div key={Symbol(item.id)}>{item.name}</div> // Error!
));

// CORRECT - Use string or number keys
items.map(item => (
  <div key={item.id}>{item.name}</div>
));

// Or generate stable string keys
items.map((item, index) => (
  <div key={`item-${item.id}-${index}`}>{item.name}</div>
));

Use crypto.randomUUID() or nanoid library if you need unique string identifiers.

5Filter Symbol properties when spreading objects

If spreading objects that might contain Symbol properties, filter them out first:

jsx
// WRONG - May spread Symbol properties
const obj = { name: 'Test', [Symbol('internal')]: 'value' };
return <Component {...obj} />; // Risk if Component renders children

// CORRECT - Filter to only string/number keys
const safeProps = Object.keys(obj).reduce((acc, key) => {
  acc[key] = obj[key];
  return acc;
}, {});
return <Component {...safeProps} />;

// Or use explicit prop passing
return <Component name={obj.name} />;

This prevents accidental Symbol props from reaching rendering logic.

6Add TypeScript types to prevent Symbol children

Use proper typing to catch Symbol usage at compile time:

typescript
// CORRECT - Strict children typing
interface MyComponentProps {
  children: React.ReactNode; // Excludes Symbols
}

// CORRECT - Strict prop typing
interface BadgeProps {
  icon: string | React.ReactElement; // No Symbols
  label: string;
}

// Use satisfies for inline type checking
const config = {
  icon: '๐ŸŽ‰', // OK
  label: 'Status'
} satisfies BadgeProps;

// This would error at compile time:
// const badConfig = {
//   icon: Symbol('bad'),
//   label: 'Status'
// } satisfies BadgeProps; // Type error!

Enable strict TypeScript checking to catch these issues before runtime.

7Inspect API responses and state for Symbol values

If the error appears with external data, check for unexpected Symbol values:

javascript
// Add defensive check in data fetching
async function fetchData() {
  const response = await fetch('/api/data');
  const data = await response.json();

  // Inspect for Symbols (shouldn't be in JSON, but check parsed data)
  console.log('Data keys:', Object.keys(data));
  console.log('All keys including Symbols:',
    Object.getOwnPropertySymbols(data));

  return data;
}

// Add runtime validation
function sanitizeData(obj) {
  return JSON.parse(JSON.stringify(obj)); // Removes Symbols
}

JSON.parse/stringify will strip Symbol properties, providing a safe data structure for rendering.

Advanced notes

Well-known Symbols: Be especially careful with JavaScript's well-known Symbols like Symbol.iterator, Symbol.toStringTag, Symbol.hasInstance, etc. These are often used in custom data structures but should never leak into React rendering. When iterating over objects with Symbol properties, use Object.keys() or Object.getOwnPropertyNames() to exclude them.

Redux and State Management: When using Redux or other state management libraries that allow Symbol keys in state, ensure your selectors return only serializable data. State serialization checks in Redux DevTools can help catch these issues early. Avoid storing Symbols in Redux state if they're meant to be rendered.

Iterator Protocol: Be cautious with custom iterables that use Symbol.iterator. If you pass an iterator directly to JSX expecting it to render its values, it will fail. Convert iterators to arrays with the spread operator: {[...iterator()]} instead of {iterator()}.

React 18+ Changes: React's rendering engine in version 18 and above has stricter type checking for children. Code that may have failed silently in older versions will now throw explicit errors about invalid children types during development.

Performance: The error occurs during React's render phase, so it will prevent the entire component tree from rendering. No partial rendering occurs, making debugging easier as the error is immediate and specific.

Prevention Pattern: Establish a convention in your codebase that Symbol values are always prefixed with SYMBOL_ (e.g., SYMBOL_STATUS_PENDING) and document that these should never be passed to React components directly. Use a linter rule or TypeScript plugin to detect Symbol usage in JSX when possible.

Frequently asked questions

What does "Symbols are not valid as React children" mean?
This error is thrown by React when you try to use a JavaScript Symbol as a child element in JSX. React's rendering engine only accepts specific types as valid children: strings, numbers, React elements, fragments, portals, booleans, null, and undefined. for() that serve as unique identifiers, but they cannot be serialized or converted to strings for DOM rendering.
How do I fix "Symbols are not valid as React children"?
This error occurs when attempting to render a JavaScript Symbol directly in JSX or pass it as a React child. React cannot render Symbols because they are non-serializable primitive types that have no string representation suitable for DOM rendering.
What causes "Symbols are not valid as React children"?
Directly rendering a Symbol in JSX: {mySymbol} or <div>{Symbol.for("key")}</div> Passing a Symbol as a prop value that the component attempts to render Using Symbol as key prop: key={Symbol("uniqueKey")} causes type conversion error
Is the "Symbols are not valid as React children" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading