nextauthjs/next-auth · error · Error

[next-auth]: `useSession` must be wrapped in a <SessionProvi

Error message

[next-auth]: `useSession` must be wrapped in a <SessionProvider />

What it means

useSession must run inside a <SessionProvider> because it reads session state from React Context. When the context value is undefined (no provider above the component) and NODE_ENV is not production, next-auth throws this error to fail fast and explain the missing wrapper.

Source

Thrown at packages/next-auth/src/react.tsx:144

/**
 * React Hook that gives you access to the logged in user's session data and lets you modify it.
 *
 * :::info
 * `useSession` is for client-side use only and when using [Next.js App Router (`app/`)](https://nextjs.org/blog/next-13-4#nextjs-app-router) you should prefer the `auth()` export.
 * :::
 */
export function useSession<R extends boolean>(
  options?: UseSessionOptions<R>
): SessionContextValue<R> {
  if (!SessionContext) {
    throw new Error("React Context is unavailable in Server Components")
  }

  // @ts-expect-error Satisfy TS if branch on line below
  const value: SessionContextValue<R> = React.useContext(SessionContext)
  if (!value && process.env.NODE_ENV !== "production") {
    throw new Error(
      "[next-auth]: `useSession` must be wrapped in a <SessionProvider />"
    )
  }

  const { required, onUnauthenticated } = options ?? {}

  const requiredAndNotLoading = required && value.status === "unauthenticated"

  React.useEffect(() => {
    if (requiredAndNotLoading) {
      const url = `${__NEXTAUTH.basePath}/signin?${new URLSearchParams({
        error: "SessionRequired",
        callbackUrl: window.location.href,
      })}`
      if (onUnauthenticated) onUnauthenticated()
      else window.location.href = url
    }
  }, [requiredAndNotLoading, onUnauthenticated])

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Wrap your app (or the subtree using useSession) in <SessionProvider> from "next-auth/react", e.g. in app/layout.tsx
  2. Ensure the component calling useSession is a client component under that provider
  3. Pass session data from the server via `<SessionProvider session={await auth()}>` in the root layout

Example fix

// before
// app/layout.tsx
export default function RootLayout({ children }) {
  return <html><body>{children}</body></html>
}
// after
import { SessionProvider } from "next-auth/react"
export default async function RootLayout({ children }) {
  const session = await auth()
  return (
    <html><body>
      <SessionProvider session={session}>{children}</SessionProvider>
    </body></html>
  )
}
Defensive patterns

Strategy: validation

Validate before calling

// In React 18+, detect a missing provider before calling the hook:
function hasSessionProvider(): boolean {
  // simplest check: wrap useSession consumers and verify via Context
  return React.useContext(SessionContext) !== undefined // within a custom hook
}
// Or guard in dev:
if (!document.querySelector('[data-session-provider]')) {
  console.warn("SessionProvider is missing")
}

Type guard

function hasSession(
  v: SessionContextValue<boolean> | null | undefined
): v is SessionContextValue<boolean> {
  return v != null
}

Try / catch

let ctx
try {
  ctx = useSession()
} catch (e) {
  if (e.message.includes("SessionProvider")) {
    // render a fallback / redirect to sign-in instead of crashing
  } else throw e
}

Prevention

When it happens

Trigger: Calling useSession in a client component whose tree does not include <SessionProvider> (typically in the root layout or a parent client component).

Common situations: Adding useSession in a new page/component without setting up SessionProvider in app/layout.tsx; provider present only in some routes while the hook is used elsewhere; migration where the provider was in _app.tsx (pages router) and never added to the app router layout.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/51d61cf38653d0b9. Report an issue: GitHub.