{"record":{"id":"25104505ef2fa9f1","repo":"nextauthjs/next-auth","slug":"data-message","errorCode":null,"errorMessage":"data.message","messagePattern":"data\\.message","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/frameworks-express/src/index.ts","lineNumber":205,"sourceCode":"    req.protocol,\n    // @ts-expect-error\n    new Headers(req.headers),\n    process.env,\n    config\n  )\n\n  const response = await Auth(\n    new Request(url, { headers: { cookie: req.headers.cookie ?? \"\" } }),\n    config\n  )\n\n  const { status = 200 } = response\n\n  const data = await response.json()\n\n  if (!data || !Object.keys(data).length) return null\n  if (status === 200) return data\n  throw new Error(data.message)\n}\n\nfunction getBasePath(req: e.Request) {\n  return req.baseUrl.split(req.params[0])[0].replace(/\\/$/, \"\")\n}\n","sourceCodeStart":187,"sourceCodeEnd":211,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/frameworks-express/src/index.ts#L187-L211","documentation":"The Express adapter's getSession fetches the session from the Auth.js backend and throws Error(data.message) whenever the HTTP status is not 200. The backend's error 'message' field is used verbatim, so the surfaced message is whatever the auth core returned (e.g. UntrustedHost, fetch failure, or a session/action error). An empty body or empty object returns null instead of throwing.","triggerScenarios":"Calling auth() / getSession(req) from an Express route while the backing Auth.js endpoint (/api/auth/session) responds non-200 — e.g. 401/404 because AUTH_SECRET is missing, the route handler isn't mounted, trusted host validation fails, or the core threw an internal error.","commonSituations":"Express apps where the auth route handler isn't correctly mounted so /auth/session 404s; AUTH_SECRET unset in production; mismatch between the Express adapter's base path and the actual handler mount point (getBasePath derives it from req.baseUrl).","solutions":["Read the thrown data.message — it comes from the Auth.js core response and names the real failure.","Verify the auth route handler (toExpressRequestHandler) is mounted and the base path matches (default /auth).","Set AUTH_SECRET in the environment of the Express process.","Log the full response status/body from /auth/session directly (curl it) to see the underlying error."],"exampleFix":"// before\nconst session = await auth(req, res) // throws opaque Error(data.message)\n// after\ntry {\n  const session = await auth(req, res)\n} catch (e) {\n  console.error(\"Session fetch failed:\", (e as Error).message)\n}","handlingStrategy":"try-catch","validationCode":"if (!process.env.AUTH_SECRET) throw new Error(\"AUTH_SECRET missing\")\n// Optionally health-check: const r = await fetch(`${origin}/auth/session`); if (!r.ok) ...\n","typeGuard":"function isSessionData(data: unknown): data is { user?: { email?: string } } & Record<string, unknown> {\n  return typeof data === \"object\" && data !== null\n}","tryCatchPattern":"try {\n  const session = await auth(req, res)\n} catch (err) {\n  console.error(\"Auth.js session error (from backend):\", (err as Error).message)\n  // treat as unauthenticated and continue, or return 401\n}","preventionTips":["Verify the auth handler is mounted and basePath matches /auth.","Set AUTH_SECRET in all deployment environments.","Smoke-test /auth/session with curl after deploying.","Never assume auth() throws only on network issues — read the backend message."],"tags":["express","session","http-response","framework-adapter"],"backgroundTag":"session-fetch-failed","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}