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

ReactINTERMEDIATEMEDIUMUpdated Dec 8, 2025ยท 130 views

This error occurs when attempting to render a JavaScript Symbol directly in JSX or pass it as a React child. React cannot convert Symbols to renderable content because they are non-serializable primitive types.

Quick fix

Fixes Symbols are not allowed 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 allowed 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 allowed as React children" error message
  • Component renders nothing or shows blank space where 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 (e.g., any)
  • 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 allowed 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 built-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.

Redux/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.

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

Symbol.for() vs Symbol(): Symbol.for() creates global Symbol registry entries, while Symbol() creates unique symbols. Neither is valid for React children, but Symbol.for() might appear in cross-module constants that accidentally get rendered.

Testing: When writing unit tests, ensure your test data doesn't include Symbol values unless you're specifically testing Symbol handling. Jest and other test frameworks may serialize Symbols in snapshots, hiding the issue until runtime.

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 (e.g., SYMBOL_STATUS_PENDING) and document that these should never be passed to React components directly. Use ESLint rules to detect Symbol usage in JSX if possible.

Frequently asked questions

What does "Symbols are not allowed 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 allowed 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 convert Symbols to renderable content because they are non-serializable primitive types.
What causes "Symbols are not allowed 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 allowed 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