This error occurs when a component using React.Children.only() receives multiple children instead of exactly one React element. It commonly happens with wrapper components, cloneElement patterns, or when passing arrays as children.
The React.Children.only() utility function is designed to validate that a component's children prop contains exactly one React elementโnot multiple elements, not an array, not text or other values. When a component internally calls React.Children.only(props.children), it's asserting that it can only work with a single child element. This error is React's way of enforcing this constraint. Many React components and libraries use Children.only() internally to ensure they receive a single child that they can manipulate, clone, or enhance with additional props. The method will throw this error if you pass multiple elements, an array (even with one element), null, undefined, or primitive values like strings or numbers. Understanding this error is crucial because it often appears when using component composition patterns, particularly with wrapper components that need to clone or enhance a single child element using React.cloneElement(). Libraries like React Router, UI component libraries (Recharts, shadcn/ui), and animation libraries frequently implement this pattern.
Check the error stack trace to find exactly which component is calling React.Children.only(). The error message will show the component tree. Look for:
Error: React.Children.only expected to receive a single React element child.
at Children.only
at YourWrapperComponent
at ParentComponentCommon culprits include wrapper components, components using the "asChild" pattern (like shadcn/ui Button), or any component that clones or enhances children. Once identified, examine how you're passing children to that component.
If you're passing multiple elements to a component, wrap them in a React Fragment. This is the cleanest solution that doesn't add extra DOM elements:
// Before (causes error)
<WrapperComponent>
<div>First element</div>
<div>Second element</div>
</WrapperComponent>
// After (fixed with Fragment)
<WrapperComponent>
<>
<div>First element</div>
<div>Second element</div>
</>
</WrapperComponent>
// Or use explicit Fragment syntax
<WrapperComponent>
<React.Fragment>
<div>First element</div>
<div>Second element</div>
</React.Fragment>
</WrapperComponent>Note: Some components explicitly use Children.only() and will still reject Fragments. In those cases, you need a real wrapper element.
If the Fragment approach doesn't work because the component explicitly rejects Fragments, wrap your content in a single container element:
// Wrap in a div
<WrapperComponent>
<div>
<h1>Title</h1>
<p>Content</p>
<button>Action</button>
</div>
</WrapperComponent>
// Or use span for inline content
<InlineWrapper>
<span>
<Icon />
<Text>Label</Text>
</span>
</InlineWrapper>This adds one extra DOM node but ensures the parent component receives exactly one child element. Use semantic HTML elements when possible (section, article, etc.) rather than generic divs.
Whitespace and text between JSX elements can count as separate children. Remove any spaces, newlines, or text between elements:
// This creates THREE children (two divs + whitespace)
<Component>
<div>First</div>
{' '} {/* This whitespace is a text node child */}
<div>Second</div>
</Component>
// This also creates multiple children (text + element)
<Component>
Some text here
<div>Element</div>
</Component>
// Fixed - only one child
<Component>
<div>
Some text here
<div>Element</div>
</div>
</Component>Be especially careful with formatted JSX that includes line breaks and indentation between elements.
If you're mapping an array to create children, React.Children.only() will reject the array even if it has only one element. Don't pass arrays directly:
// Wrong - array is not a single element
<Component>
{items.map(item => <div key={item.id}>{item.name}</div>)}
</Component>
// Wrong - still an array with one item
<Component>
{[<div key="1">Single item</div>]}
</Component>
// Fixed - wrap the mapped array
<Component>
<div>
{items.map(item => <div key={item.id}>{item.name}</div>)}
</div>
</Component>
// Or if you only need one item, render it directly
<Component>
<div key={items[0].id}>{items[0].name}</div>
</Component>Many modern UI libraries (shadcn/ui, Radix UI) use an "asChild" prop that merges props into a single child using cloneElement. This pattern requires exactly one child:
// shadcn/ui Button with asChild
// Wrong - multiple children
<Button asChild>
<Icon />
<span>Click me</span>
</Button>
// Correct - single child element
<Button asChild>
<a href="/home">
<Icon />
<span>Click me</span>
</a>
</Button>
// Or don't use asChild
<Button>
<Icon />
<span>Click me</span>
</Button>When asChild is true, the component expects to clone exactly one child and merge its own props into it. Read the component documentation to understand when asChild is appropriate.
If you're maintaining a component that uses Children.only(), consider whether this constraint is necessary. Modern React patterns often prefer render props or composition:
// Instead of this (restrictive)
function Wrapper({ children }: { children: ReactElement }) {
const onlyChild = React.Children.only(children);
return React.cloneElement(onlyChild, { className: 'wrapper' });
}
// Consider this (flexible)
function Wrapper({ render }: { render: (props: any) => ReactElement }) {
return render({ className: 'wrapper' });
}
// Usage
<Wrapper render={(props) => <div {...props}>Content</div>} />
// Or use component props
function Wrapper({ component: Component, ...props }: { component: ComponentType }) {
return <Component {...props} className="wrapper" />;
}This makes the API more flexible and avoids the single-child constraint. Only use Children.only() when you genuinely need to validate and clone a single element.
Why React.Children.only() Exists: This utility is specifically designed for components that need to clone or enhance a single child element using React.cloneElement(). It prevents subtle bugs where a component expects to manipulate one element but receives multiple, which would require different logic (React.Children.map).
Fragment Limitations: While Fragments (<></>) group elements without adding DOM nodes, they're still treated as a wrapper element by React.Children.only(). Some components may accept Fragments, but others explicitly check for a single non-Fragment element. Test your specific use case.
TypeScript and Children.only: When using TypeScript, type your children prop as ReactElement (not ReactNode) to catch this error at compile time: "children: ReactElement" will enforce a single element, while "children: ReactNode" allows multiple children, arrays, strings, etc.
Next.js Specific Issues: This error commonly appears in Next.js applications when using Link components from next/link or when wrapping page components. The Next.js Link component accepts only one child, so wrap multiple elements before passing them to Link.
Performance Consideration: Using React.Children.only() adds runtime validation overhead. For performance-critical components that you control fully, consider using TypeScript types to enforce single children at compile time rather than runtime validation.
Debugging Tip: To see exactly what children are being passed, temporarily log them: "console.log('Children:', React.Children.toArray(props.children))". This reveals hidden text nodes, whitespace, or arrays that aren't obvious in JSX.
Library-Specific Patterns: Common libraries with this pattern include Recharts (chart components), React Router (Link), Framer Motion (motion components), and Radix UI primitives. Always check the library documentation for the "asChild" or similar composition patterns that require single children.
Alternative Patterns: Modern React development increasingly favors render props, component composition via props, or hooks over child manipulation patterns. If you're designing a new API, consider these alternatives before using Children.only() and cloneElement().
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite