Fix: React Warning: Failed prop type
Quick Answer
How to fix the React 'Warning: Failed prop type' error. Covers wrong prop types, missing required props, children type issues, shape and oneOf PropTypes, migrating to TypeScript, default props, and third-party component mismatches.
The Error
You render a React component and see this warning in the console:
Warning: Failed prop type: Invalid prop `name` of type `number` supplied to `UserCard`, expected `string`.Or one of its variations:
Warning: Failed prop type: The prop `onClick` is marked as required in `Button`, but its value is `undefined`.Warning: Failed prop type: Invalid prop `status` of value `active` supplied to `Badge`, expected one of ["success","error","warning"].The component might still render, but something is off. A string shows up where a number should be, a callback never fires, or a child component silently breaks because it received the wrong data shape.
This warning comes from React’s prop-types library. It tells you that a component received a prop that does not match its declared type expectations. Ignoring it leads to subtle bugs that are harder to track down later.
Why This Happens
React components can declare what types of props they expect using the prop-types package. When a component receives a prop that violates those declarations, React fires a warning in development mode.
The root causes fall into a few categories:
- Type mismatch: You pass a string where a number is expected, or an object where an array is needed.
- Missing required prop: A prop is marked
.isRequiredbut you never pass it. - Wrong object shape: The prop expects an object with specific keys and types, but the object you pass has a different structure.
- Enum violation: The prop expects one of a fixed set of values, but you pass something outside that set.
- Children type mismatch: The component expects a single child element but receives multiple, or vice versa.
- Third-party component expectations: A library component expects props in a specific format that differs from what you assume.
These warnings only appear in development mode. React strips PropTypes checks in production builds for performance. That means if you ignore these warnings during development, bugs will ship silently to production.
Common Mistake: Many developers dismiss PropTypes warnings because the app “still works.” But these warnings often indicate data flowing incorrectly through your component tree. A prop type mismatch in a parent component can cause crashes or wrong behavior several layers deeper, making the real bug much harder to find.
Fix 1: Fix Wrong Prop Type (String vs Number, Object vs Array)
The most common variant of this warning looks like this:
Warning: Failed prop type: Invalid prop `age` of type `string` supplied to `Profile`, expected `number`.This happens when the data type you pass does not match the PropTypes declaration. A frequent source is form inputs and URL parameters, which are always strings.
Check the component’s PropTypes definition:
Profile.propTypes = {
age: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
};Then check what you are passing:
// Wrong - age is a string from the URL params
const age = searchParams.get("age"); // returns "25" (string)
<Profile name="Alice" age={age} />Convert the value to the correct type before passing it:
// Correct - parse the string to a number
const age = Number(searchParams.get("age"));
<Profile name="Alice" age={age} />The same issue arises with objects vs arrays. If a component expects an array:
ItemList.propTypes = {
items: PropTypes.array.isRequired,
};But you pass an object:
// Wrong - API returned an object with a data key
<ItemList items={response} />
// Correct - extract the array
<ItemList items={response.data} />Always check the type of data coming from APIs, URL parameters, form inputs, and localStorage. These are the most common sources of type mismatches.
If you are dealing with type conversion issues elsewhere in your codebase, the same principles apply to TypeScript type errors where the compiler catches these at build time instead of runtime.
Fix 2: Fix Required Prop Not Passed
This warning fires when a prop is marked as required but is missing:
Warning: Failed prop type: The prop `onSubmit` is marked as required in `ContactForm`, but its value is `undefined`.There are three common causes.
You forgot to pass the prop entirely:
// Wrong - missing onSubmit
<ContactForm name="Contact Us" />
// Correct
<ContactForm name="Contact Us" onSubmit={handleSubmit} />You passed the prop but it is undefined at that point:
function App() {
const [handler, setHandler] = useState();
// Wrong on first render - handler is undefined
return <ContactForm onSubmit={handler} />;
}Fix this by providing a default value or conditionally rendering:
// Option 1: default value
const [handler, setHandler] = useState(() => () => {});
// Option 2: conditional render
return handler ? <ContactForm onSubmit={handler} /> : <Loading />;You destructured props and accidentally renamed or skipped it:
// Wrong - destructured as "submit" but passed as "onSubmit"
function ParentComponent({ submit }) {
return <ContactForm onSubmit={submit} />;
}
// The parent's parent passes "onSubmit", not "submit"
<ParentComponent onSubmit={handleSubmit} />Fix the destructuring to match the actual prop name:
function ParentComponent({ onSubmit }) {
return <ContactForm onSubmit={onSubmit} />;
}This kind of prop-drilling bug becomes common in deep component trees. If you are managing state across many levels, consider whether useState patterns or a state management solution would simplify things.
Fix 3: Fix Children Prop Type
Components can declare expectations about their children:
Wrapper.propTypes = {
children: PropTypes.element.isRequired,
};PropTypes.element expects a single React element. If you pass multiple children or a string, the warning fires:
Warning: Failed prop type: Invalid prop `children` of type `array` supplied to `Wrapper`, expected a single ReactElement.Understand the difference between the children PropTypes:
| PropType | Accepts |
|---|---|
PropTypes.element | Single React element (<div />) |
PropTypes.node | Anything renderable (string, number, element, array, fragment) |
PropTypes.arrayOf(PropTypes.element) | Array of React elements |
PropTypes.oneOfType([...]) | Multiple possible types |
If you control the component, decide which is correct:
// If the component should accept anything renderable
Wrapper.propTypes = {
children: PropTypes.node.isRequired,
};
// If it strictly needs a single element, wrap multiple children
<Wrapper>
<div>
<Header />
<Content />
</div>
</Wrapper>If you are passing objects as children by accident, you will hit a different error entirely. See React: Objects are not valid as a React child for that case.
Fix 4: Fix Shape/Exact PropTypes for Objects
When a component expects an object with a specific structure, it uses PropTypes.shape or PropTypes.exact:
UserCard.propTypes = {
user: PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
}).isRequired,
};The warning fires when the object you pass is missing required keys or has keys with wrong types:
Warning: Failed prop type: Invalid prop `user.email` of type `number` supplied to `UserCard`, expected `string`.Check that the object you are passing matches the expected shape:
// Wrong - email is missing, id is a string
const user = { id: "abc", name: "Alice" };
// Correct
const user = { id: 1, name: "Alice", email: "[email protected]" };shape vs exact: PropTypes.shape allows extra keys that are not declared. PropTypes.exact warns if the object has any keys not listed in the declaration. If you see warnings about extra keys, the component uses exact:
// PropTypes.exact will warn about "role" since it is not declared
const user = { id: 1, name: "Alice", email: "[email protected]", role: "admin" };When working with API data, the shape of the response may change between environments or API versions. Always validate API responses before passing them directly as props:
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then((data) => {
// Normalize the data to match the expected shape
setUser({
id: Number(data.id),
name: String(data.name),
email: String(data.email),
});
});
}, [userId]);
if (!user) return <Loading />;
return <UserCard user={user} />;
}Fix 5: Fix Enum/oneOf PropTypes
PropTypes.oneOf restricts a prop to a specific set of values:
Badge.propTypes = {
variant: PropTypes.oneOf(["success", "error", "warning", "info"]).isRequired,
};The warning fires when you pass a value outside that set:
Warning: Failed prop type: Invalid prop `variant` of value `danger` supplied to `Badge`, expected one of ["success","error","warning","info"].The fix is straightforward --- use one of the allowed values:
// Wrong
<Badge variant="danger" />
// Correct
<Badge variant="error" />But the real-world cause is usually more subtle. The value comes from a variable, and that variable contains something unexpected:
function StatusBadge({ status }) {
// API returns "active"/"inactive", but Badge expects "success"/"error"
return <Badge variant={status} />;
}Create a mapping between your data values and the component’s expected values:
const STATUS_TO_VARIANT = {
active: "success",
inactive: "error",
pending: "warning",
unknown: "info",
};
function StatusBadge({ status }) {
const variant = STATUS_TO_VARIANT[status] || "info";
return <Badge variant={variant} />;
}Pro Tip: When using
PropTypes.oneOf, export the allowed values as a constant array from the component file. This way, consuming components can reference the same set of values instead of hardcoding strings that might go out of sync:// Badge.jsx export const BADGE_VARIANTS = ["success", "error", "warning", "info"]; Badge.propTypes = { variant: PropTypes.oneOf(BADGE_VARIANTS).isRequired, };
Similarly, PropTypes.oneOfType lets a prop accept multiple types:
Input.propTypes = {
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]).isRequired,
};If the warning fires for oneOfType, the value you pass does not match any of the listed types. Check what type the value actually is using typeof or console.log.
Fix 6: Migrate from PropTypes to TypeScript
PropTypes provide runtime type checking in development only. TypeScript provides compile-time type checking that catches errors before the code runs. If you are still using PropTypes and hitting frequent type warnings, migrating to TypeScript eliminates an entire class of bugs.
Replace PropTypes with TypeScript interfaces:
// Before: PropTypes
import PropTypes from "prop-types";
function UserCard({ user, onSelect }) {
return (
<div onClick={() => onSelect(user.id)}>
{user.name} ({user.email})
</div>
);
}
UserCard.propTypes = {
user: PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
}).isRequired,
onSelect: PropTypes.func.isRequired,
};// After: TypeScript
interface User {
id: number;
name: string;
email: string;
}
interface UserCardProps {
user: User;
onSelect: (id: number) => void;
}
function UserCard({ user, onSelect }: UserCardProps) {
return (
<div onClick={() => onSelect(user.id)}>
{user.name} ({user.email})
</div>
);
}The TypeScript version catches type mismatches at build time. You will see errors in your editor as you type, not warnings in the browser console after the component renders.
Steps to migrate incrementally:
- Rename
.jsxfiles to.tsxone at a time. - Add TypeScript interfaces for each component’s props.
- Remove
import PropTypesand delete the.propTypesassignment. - Fix any type errors the compiler finds.
- Run
npm uninstall prop-typesonce all components are migrated.
You do not need to migrate everything at once. TypeScript and PropTypes can coexist in the same project. Start with the components that cause the most PropTypes warnings.
For more on TypeScript type errors you may encounter during migration, see TypeScript: Argument not assignable to parameter.
Fix 7: Fix Default Props with Functional Components
When a prop is optional but needs a fallback value, you might use defaultProps:
function Greeting({ name }) {
return <h1>Hello, {name}</h1>;
}
Greeting.propTypes = {
name: PropTypes.string,
};
Greeting.defaultProps = {
name: "World",
};This works, but defaultProps on functional components is deprecated as of React 18.3 and will be removed in a future version. The warning may show up alongside your PropTypes warnings:
Warning: Greeting: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.Use JavaScript default parameters instead:
function Greeting({ name = "World" }) {
return <h1>Hello, {name}</h1>;
}
Greeting.propTypes = {
name: PropTypes.string,
};Default parameters also interact better with PropTypes. When you use defaultProps, the PropTypes check runs after defaults are applied, so a required check will never fail. With default parameters, the behavior is the same --- the destructured value will have the default if the prop is not passed.
Watch out for undefined vs null:
// Default parameter kicks in for undefined, NOT for null
function Greeting({ name = "World" }) {
return <h1>Hello, {name}</h1>;
}
<Greeting name={undefined} /> // Renders "Hello, World"
<Greeting name={null} /> // Renders "Hello, " (null is not undefined)If your component might receive null, add an explicit check:
function Greeting({ name = "World" }) {
const displayName = name ?? "World";
return <h1>Hello, {displayName}</h1>;
}When components have many optional props with defaults, destructure them clearly at the top of the function:
function DataTable({
data = [],
pageSize = 10,
sortable = true,
onRowClick = () => {},
emptyMessage = "No data available",
}) {
// Component logic here
}This approach is cleaner than a separate defaultProps object and keeps defaults co-located with the parameter declarations.
Fix 8: Fix Third-Party Component Prop Type Mismatches
Third-party libraries often define strict PropTypes on their components. You see a warning but cannot change the library’s PropTypes declaration.
Common scenarios:
The library expects a specific component type as a child:
Warning: Failed prop type: Invalid prop `children` supplied to `TabPanel`, expected a single ReactElement of type `Tab`.Check the library’s documentation for the correct usage pattern. Many UI libraries require specific child component types:
// Wrong - plain divs inside TabPanel
<TabPanel>
<div>Tab 1 Content</div>
<div>Tab 2 Content</div>
</TabPanel>
// Correct - use the library's Tab component
<TabPanel>
<Tab label="Tab 1">Tab 1 Content</Tab>
<Tab label="Tab 2">Tab 2 Content</Tab>
</TabPanel>The library updated and changed expected prop types:
After updating a dependency, new PropTypes warnings may appear. Check the library’s changelog or migration guide for breaking changes:
npm info react-some-library changelogOr visit the library’s GitHub releases page. Look for prop renames, type changes, or deprecated props.
You are passing extra props that the component does not expect:
Some libraries use PropTypes.exact which warns about unknown props. Filter out extra props before passing them:
// Wrong - spreading all props includes unexpected ones
<LibraryButton {...props} />
// Correct - pick only the props the component expects
const { label, onClick, disabled, ...rest } = props;
<LibraryButton label={label} onClick={onClick} disabled={disabled} />You are wrapping a library component and breaking its prop chain:
// Wrong - the wrapper swallows the "variant" prop
function MyButton({ children, ...rest }) {
return <LibraryButton {...rest}>{children}</LibraryButton>;
}
// Usage - variant never reaches LibraryButton because it is not in rest
<MyButton variant="primary">Click</MyButton>Make sure you are not accidentally excluding props in the wrapper. Use console.log(rest) to verify what props are being forwarded.
If a third-party library has genuinely incorrect PropTypes (the prop works but the warning fires), check the library’s issue tracker. This is a known pattern --- report it and suppress the specific warning temporarily:
// Temporary suppression - remove when library fixes the issue
const originalError = console.error;
console.error = (...args) => {
if (typeof args[0] === "string" && args[0].includes("Failed prop type")) {
return;
}
originalError(...args);
};Warning: Only use console suppression as a last resort. It hides all PropTypes warnings, including legitimate ones. A better approach is to pin the library version and wait for a fix, or wrap the component with correct types.
If you are hitting similar issues with React hook calls inside third-party components, see React: Invalid hook call for related debugging steps.
Still Not Working?
If the warning persists after trying the fixes above, try these less obvious approaches.
Check for multiple React versions. If your project bundles two copies of React (common with linked packages or monorepos), PropTypes from one copy cannot validate components from another. Run this to check:
npm ls reactIf you see two versions, resolve the duplication by adding a resolutions field in package.json (Yarn) or overrides (npm):
{
"overrides": {
"react": "^18.2.0"
}
}Check for stale PropTypes after refactoring. When you change a component’s API but forget to update its PropTypes, the declarations become stale. The component works but the PropTypes no longer match reality. Review the component’s PropTypes and update them to match the current implementation.
Look at the component hierarchy. The warning names the component that received the bad prop, but the bug is in the parent that passes it. Trace the prop back through the component tree to find where the wrong value originates.
Check for async data timing. A prop might be the correct type most of the time but temporarily wrong during loading states. Add null checks or loading guards:
if (!data) return <Skeleton />;
return <DataDisplay items={data.items} />;Use React DevTools. Install the React DevTools browser extension. Select the component with the warning and inspect its props in real time. You can see the exact value and type of every prop, which makes it obvious where the mismatch is.
Check render keys. If the warning only appears intermittently, it might be caused by list re-rendering where items get shuffled and the wrong data ends up in the wrong component. Ensure you are using stable, unique keys for lists.
If you have migrated to TypeScript and still see PropTypes warnings, you likely have residual .propTypes declarations on some components. Search your codebase for .propTypes and remove them once TypeScript interfaces cover the same checks:
grep -r "\.propTypes" src/Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: React TypeError: Cannot read property 'map' of undefined
How to fix React TypeError Cannot read property map of undefined caused by uninitialized state, async data loading, wrong API response structure, and missing default values.
Fix: React Cannot update a component while rendering a different component
How to fix React Cannot update a component while rendering a different component caused by setState during render, context updates in render, and Redux dispatch in render.
Fix: Invalid hook call. Hooks can only be called inside of the body of a function component
How to fix the React Invalid hook call error caused by mismatched React versions, duplicate React copies, calling hooks outside components, and class component usage.
Fix: Objects are not valid as a React child (found: [object Object])
How to fix the React error 'Objects are not valid as a React child' caused by rendering plain objects, Date objects, Promises, or API responses directly in JSX.