This error occurs when a component attempts to consume a React Context using useContext, but the component tree is not wrapped in the corresponding Context.Provider. React Context requires providers to be positioned higher in the component tree than any consumers.
This error indicates that a component is trying to access values from a React Context, but the Context.Provider is either missing entirely, placed at the wrong level in the component tree, or the component consuming the context is rendered outside the provider's scope. React Context follows a provider-consumer pattern where the Provider component wraps the component tree and makes values available to all descendants. When you call useContext(MyContext) in a component, React walks up the tree looking for the nearest matching Provider. If it doesn't find one, the context will have its default value (often undefined), which commonly triggers errors when you try to access properties or call methods on undefined values. This issue frequently occurs during testing when components are rendered in isolation, during routing when providers aren't configured at the app root level, or when reorganizing component hierarchies without accounting for context dependencies.
Look at the error message or stack trace to identify which context hook is failing. If the error shows a component name, find where that component uses useContext:
// Find lines like this in your component
const value = useContext(MyContext);
// or
const { user, setUser } = useContext(AuthContext);Once identified, you'll need to ensure the corresponding Provider wraps this component higher in the tree.
The most common fix is ensuring your provider wraps the entire application. For standard React apps, this typically goes in your main App component or index file:
// src/App.tsx
import { MyContext } from './contexts/MyContext';
function App() {
const contextValue = {
// your context values
};
return (
<MyContext.Provider value={contextValue}>
<Router>
<Routes>
{/* All your routes here */}
</Routes>
</Router>
</MyContext.Provider>
);
}For Next.js App Router, wrap your root layout:
// app/layout.tsx
import { MyContextProvider } from '@/contexts/MyContext';
export default function RootLayout({ children }) {
return (
<html>
<body>
<MyContextProvider>
{children}
</MyContextProvider>
</body>
</html>
);
}Verify that the provider is positioned higher in the tree than any consumers. A common mistake is placing the provider inside a component that also consumes it:
// ❌ WRONG - Consumer and Provider at same level
function Dashboard() {
const { user } = useContext(AuthContext); // Will fail!
return (
<AuthContext.Provider value={authValue}>
<UserProfile />
</AuthContext.Provider>
);
}
// ✅ CORRECT - Provider wraps consumers
function App() {
return (
<AuthContext.Provider value={authValue}>
<Dashboard /> {/* Can safely use context */}
</AuthContext.Provider>
);
}Use React DevTools to visualize the component tree and confirm the Provider appears above all consumers.
For better organization and to avoid repetition, create a dedicated provider component that encapsulates context creation and state management:
// contexts/AuthContext.tsx
import { createContext, useContext, useState, ReactNode } from 'react';
interface AuthContextType {
user: User | null;
login: (email: string, password: string) => Promise<void>;
logout: () => void;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const login = async (email: string, password: string) => {
// login logic
const userData = await loginAPI(email, password);
setUser(userData);
};
const logout = () => {
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
// Custom hook with built-in error checking
export function useAuth() {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}Then use it in your app:
// App.tsx
import { AuthProvider } from './contexts/AuthContext';
function App() {
return (
<AuthProvider>
<YourApp />
</AuthProvider>
);
}The custom hook provides a clear error message if used incorrectly.
If tests are failing with this error, wrap your test components with the necessary providers:
// test-utils.tsx
import { render } from '@testing-library/react';
import { AuthProvider } from '@/contexts/AuthContext';
import { ThemeProvider } from '@/contexts/ThemeContext';
export function renderWithProviders(ui: React.ReactElement) {
return render(
<AuthProvider>
<ThemeProvider>
{ui}
</ThemeProvider>
</AuthProvider>
);
}
// In your tests
import { renderWithProviders } from './test-utils';
test('user profile displays correctly', () => {
renderWithProviders(<UserProfile />);
// assertions
});For more complex scenarios, create a test wrapper that accepts custom provider values:
export function renderWithAuth(
ui: React.ReactElement,
{ user = mockUser, ...options } = {}
) {
const Wrapper = ({ children }) => (
<AuthContext.Provider value={{ user, login: vi.fn(), logout: vi.fn() }}>
{children}
</AuthContext.Provider>
);
return render(ui, { wrapper: Wrapper, ...options });
}Ensure all files import the context from the same location. Having multiple context instances will cause providers and consumers to mismatch:
// ✅ CORRECT - Single source of truth
// contexts/AuthContext.ts - CREATE HERE
export const AuthContext = createContext<AuthContextType>(defaultValue);
// components/Login.tsx - IMPORT HERE
import { AuthContext } from '@/contexts/AuthContext';
// components/Profile.tsx - IMPORT FROM SAME LOCATION
import { AuthContext } from '@/contexts/AuthContext';
// ❌ WRONG - Creating context in multiple places
// components/Login.tsx
const AuthContext = createContext(); // Different instance!
// components/Profile.tsx
const AuthContext = createContext(); // Another different instance!Search your codebase for duplicate context definitions:
grep -r "createContext" src/Multiple Nested Providers: When using multiple contexts, the order of nesting typically doesn't matter for functionality, but consider performance implications. Place providers that change frequently closer to the components that use them to minimize re-renders.
Context Default Values: The default value passed to createContext is only used when a component has no matching Provider above it in the tree. In production apps, this default is rarely used - instead, implement a custom hook that throws a descriptive error if the provider is missing.
React Server Components: In Next.js 13+ App Router, Context Providers must be Client Components (marked with 'use client'). Create a separate provider file and import it into your Server Component layout:
// providers/Providers.tsx
'use client';
export function Providers({ children }) {
return <AuthProvider>{children}</AuthProvider>;
}
// app/layout.tsx (Server Component)
import { Providers } from './providers/Providers';
export default function RootLayout({ children }) {
return <html><body><Providers>{children}</Providers></body></html>;
}Development vs Production: This error is often only caught at runtime, not during compilation. TypeScript can help by typing your context properly, but won't prevent incorrect component tree structure. Consider adding runtime checks in development mode.
Performance: Avoid creating new objects or functions inline in the Provider value prop, as this causes all consumers to re-render on every Provider render. Memoize values with useMemo or useState:
const value = useMemo(() => ({ user, login, logout }), [user]);
return <AuthContext.Provider value={value}>...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