This error occurs when useContext is called with an invalid argument, most commonly when passing Context.Consumer instead of the Context object itself, or when the Context Provider is missing from the component tree.
This error indicates that the `useContext` hook received an argument that is not a valid Context object created by `React.createContext()`. React's Context API requires that you pass the exact Context object to `useContext`, not one of its properties like `.Consumer` or `.Provider`. The error can also manifest when the context value is undefined because no Provider exists in the component tree above the component calling `useContext`. While React won't throw an error in this case, your application will receive `undefined` (or the default value), which often leads to runtime errors when trying to access properties on the undefined value. This is a design-time error that reveals incorrect usage of the Context API. The Context object passed to `useContext` must be exactly the same object (determined by `===` comparison) that was created with `createContext` and used to render the Provider component.
The most common mistake is passing Context.Consumer or Context.Provider instead of the Context object.
Incorrect:
// ❌ Wrong - passing Consumer
const value = useContext(MyContext.Consumer);
// ❌ Wrong - passing Provider
const value = useContext(MyContext.Provider);Correct:
// ✅ Correct - pass the Context object directly
const value = useContext(MyContext);Make sure you're importing and using the Context object created by createContext(), not one of its properties.
The component calling useContext must be rendered inside the corresponding <Context.Provider> in the component tree.
Check your component hierarchy:
// ✅ Correct - Provider wraps the component
function App() {
return (
<MyContext.Provider value={someValue}>
<ComponentThatUsesContext />
</MyContext.Provider>
);
}
function ComponentThatUsesContext() {
const value = useContext(MyContext); // ✅ Works - Provider is above
return <div>{value}</div>;
}Common mistake:
// ❌ Wrong - using context in the same component as Provider
function App() {
const value = useContext(MyContext); // ❌ Fails - no Provider above
return (
<MyContext.Provider value={someValue}>
<Child />
</MyContext.Provider>
);
}A best practice is to create a custom hook that throws a clear error if the context is undefined. This helps catch missing Provider wrappers early.
import { createContext, useContext } from 'react';
const MyContext = createContext(undefined);
// Custom hook with validation
export function useMyContext() {
const context = useContext(MyContext);
if (context === undefined) {
throw new Error(
'useMyContext must be used within a MyContext.Provider'
);
}
return context;
}
// Provider component for convenience
export function MyProvider({ children, value }) {
return (
<MyContext.Provider value={value}>
{children}
</MyContext.Provider>
);
}
// Usage
function MyComponent() {
const value = useMyContext(); // Will throw clear error if Provider missing
return <div>{value}</div>;
}This pattern makes it immediately obvious when you forget to wrap a component with the Provider.
If you're importing the same Context from different places, or have multiple versions of React installed, the Context object comparison will fail because they're not the same instance.
Check for duplicate React packages:
npm ls react
# or
yarn list reactIf you see multiple versions, deduplicate them:
npm dedupe
# or
yarn dedupe
# or
pnpm dedupeVerify Context is imported from a single source:
// ✅ Correct - all files import from same location
// contexts/MyContext.js
export const MyContext = createContext();
// ComponentA.js
import { MyContext } from './contexts/MyContext';
// ComponentB.js
import { MyContext } from './contexts/MyContext'; // Same fileSymlinks and monorepo setups can cause duplicate module instances. Use tools like Webpack's resolve.alias to ensure React resolves to a single instance.
If only some components can access the context, the Provider might not be high enough in the tree.
Move Provider to app root or layout:
// App.js or _app.js (Next.js)
function App({ Component, pageProps }) {
return (
<AuthProvider>
<ThemeProvider>
<Component {...pageProps} />
</ThemeProvider>
</AuthProvider>
);
}For Next.js App Router:
// app/layout.js
export default function RootLayout({ children }) {
return (
<html>
<body>
<MyProvider>
{children}
</MyProvider>
</body>
</html>
);
}The Provider should wrap all components that need access to the context.
While createContext(defaultValue) accepts a default value, relying on it can mask Provider configuration errors.
Instead of relying on defaults:
// ❌ Silent failure - uses default if Provider missing
const MyContext = createContext({ user: null });
function MyComponent() {
const { user } = useContext(MyContext);
// If Provider is missing, you get { user: null } with no error
}Prefer explicit validation:
// ✅ Fail loudly - catches configuration errors
const MyContext = createContext(undefined);
function useMyContext() {
const context = useContext(MyContext);
if (!context) {
throw new Error('Provider missing');
}
return context;
}This approach ensures you catch Provider configuration issues during development rather than in production.
Verify the context works correctly:
function TestComponent() {
const value = useMyContext();
console.log('Context value:', value);
return (
<div>
<p>Context is working!</p>
<pre>{JSON.stringify(value, null, 2)}</pre>
</div>
);
}
// In your app
<MyProvider value={{ test: 'data' }}>
<TestComponent />
</MyProvider>Check the browser console to confirm the context value is being received correctly. If you see your data logged, the context is working.
Next.js Considerations:
In Next.js App Router, Context Providers must be used in Client Components (marked with 'use client'). Create a separate provider component file with the directive, then import it into your layout.
TypeScript Type Safety:
When using TypeScript, you can make the context type-safe by not allowing undefined:
type MyContextType = { user: User; theme: string };
const MyContext = createContext<MyContextType | undefined>(undefined);
function useMyContext(): MyContextType {
const context = useContext(MyContext);
if (!context) throw new Error('Provider missing');
return context; // Type is MyContextType, not undefined
}Performance Note:
Every component using useContext will re-render when the Provider's value changes. To optimize, split contexts by concern (e.g., separate AuthContext and ThemeContext) or memoize the context value with useMemo.
Testing:
When testing components that use context, wrap them with the Provider in your test setup:
render(
<MyProvider value={mockValue}>
<ComponentUnderTest />
</MyProvider>
);React DevTools:
Use React DevTools to inspect the component tree and verify that the Provider component appears above the component calling useContext. The Context value will be visible in the component inspector.
Prop spreading could cause security issues
Prop spreading could cause security issues
Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
React Hook useEffect placed inside a condition
Hook can only be called inside the body of a function component
Hook can only be called inside the body of a function component
Rollup failed to resolve import during build
How to fix "Rollup failed to resolve import" in React