How to Debug “Expected a string, got object” Error in React JSX

When working with React, one of the most confusing runtime errors developers often face is:
Error: Objects are not valid as a React child (found: object with keys {...}). If you meant to render a collection of children, use an array instead.
Or sometimes in a slightly different wording:
Expected a string, got object.
This error typically occurs when you try to render a JavaScript object directly in JSX, which React doesn’t allow. This issue often arises when you’re handling API responses, complex state objects, or passing data between components.
In this comprehensive guide, you’ll learn why this error happens, how to resolve it, and the best practices to prevent it in your React applications.
Why Does This Error Happen?
JSX is a syntax extension for JavaScript that lets you write UI elements using XML-like tags. It is designed to render:
- Strings (e.g.,
"hello world"
) - Numbers (e.g.,
42
) - Booleans (used conditionally)
- Arrays of renderable nodes (e.g.,
[<div>One</div>, <div>Two</div>]
) - Valid React elements (e.g.,
<Component />
)
However, JSX cannot directly render plain JavaScript objects (like { name: "Alice", age: 25 }
) unless you explicitly tell it how.
Problematic Example
Code That Fails
function UserProfile() {
const user = { name: "Alice", age: 25 };
return <div>{user}</div>;
}
Error Output
Error: Objects are not valid as a React child (found: object with keys {name, age})
Why It Fails
React encounters the object { name: "Alice", age: 25 }
and attempts to render it as a text node in the DOM. Since it doesn’t know how to turn an object into a string or component, it throws a runtime error.
How to Fix the Error
1. Access Object Properties Directly
Instead of rendering the whole object, render specific properties like strings or numbers.
function UserProfile() {
const user = { name: "Alice", age: 25 };
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
</div>
);
}
This approach is clean, intentional, and avoids the error.
2. Use JSON.stringify()
(Only for Debugging)
If you just want to inspect the structure of the object—for example, while debugging—wrap it in JSON.stringify()
.
function DebugComponent() {
const data = { status: "active", level: 5 };
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
Note: This is useful for debugging, logging, or quick development. However, it is not suitable for production UIs.
3. Loop Through Arrays of Objects with .map()
If you receive an array of objects (like users from an API), use .map()
to render them correctly.
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" }
];
function UserList() {
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
Here, you’re rendering individual string values from the object properties, not the entire object.
4. Use Conditional Rendering and Optional Chaining
If the object might be null
, undefined
, or incomplete, add a fallback using optional chaining (?.
) and logical operators.
function Product({ details }) {
return (
<div>
<p>Product Name: {details?.name || "N/A"}</p>
<p>Price: {details?.price || "Not available"}</p>
</div>
);
}
This approach helps avoid both rendering errors and runtime crashes from accessing undefined properties.
Additional Debugging Tips
1. Log the Value Before Rendering
Use console.log()
to see the structure of what you’re trying to render.
console.log("User data:", user);
If the output is an object, and you are rendering {user}
directly in JSX, you’ll know exactly what to fix.
2. Check Data Types Before Rendering
Add defensive checks before rendering to catch non-renderable types.
if (typeof value === 'object' && value !== null) {
console.warn("Attempting to render an object:", value);
}
3. Validate API Responses
Many times, this error is caused by assuming that data from an API is ready to be rendered. Ensure that your data has loaded and is in the expected format.
if (!user || typeof user.name !== "string") {
return <div>Loading or invalid user data...</div>;
}
Best Practices to Avoid This Error
- Never pass whole objects into JSX unless you’re using
JSON.stringify()
for debugging. - Destructure or extract properties before rendering.
- Use optional chaining or fallback values for incomplete or undefined data.
- Always map over arrays of objects to generate lists.
- Avoid blindly rendering API data without checking its structure.
Real-World Use Case: Rendering API Response Safely
function UserCard({ user }) {
if (!user || typeof user !== "object") {
return <div>No user data available.</div>;
}
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
</div>
);
}
In this example, we’re validating the incoming user
prop and only accessing specific fields that React can render safely.
Final Thoughts
The “Expected a string, got object” error is a sign that you’re trying to render a non-primitive value directly in JSX. While frustrating at first, this error reinforces a core React principle: JSX must resolve to valid renderable content.
By understanding how React expects content to be structured and by using debugging and conditional logic appropriately, you can easily fix and avoid this error.
Keep your components clean, validate your data, and render only what JSX can handle. Doing so will lead to more robust, bug-free React applications.

I’m Shreyash Mhashilkar, an IT professional who loves building user-friendly, scalable digital solutions. Outside of coding, I enjoy researching new places, learning about different cultures, and exploring how technology shapes the way we live and travel. I share my experiences and discoveries to help others explore new places, cultures, and ideas with curiosity and enthusiasm.