{"record":{"id":"668dfd174074e782","repo":"mastra-ai/mastra","slug":"session-validation-failed","errorCode":null,"errorMessage":"Session validation failed","messagePattern":"Session validation failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"auth/studio/src/index.ts","lineNumber":236,"sourceCode":"\n    return `${this.sharedApiUrl}/auth/login?${params.toString()}`;\n  }\n\n  async handleCallback(code: string, _state: string): Promise<SSOCallbackResult<StudioUser>> {\n    // The shared API already consumed the OAuth code and passes the sealed\n    // session directly as the `code` parameter in the redirect to this callback.\n    // Validate it to get user info.\n    this.logger.debug('SSO callback: validating sealed session via shared API', {\n      sharedApiUrl: this.sharedApiUrl,\n      codeLength: code?.length,\n    });\n    const user = await this.verifySessionCookie(code);\n    if (!user) {\n      this.logger.error('SSO callback: session validation failed — verifySessionCookie returned null', {\n        sharedApiUrl: this.sharedApiUrl,\n        codeLength: code?.length,\n      });\n      throw new Error('Session validation failed');\n    }\n\n    // Omit `cookies` so the Mastra server fallback path calls\n    // createSession() + getSessionHeaders() to build a cookie scoped to\n    // the deployed instance's domain.\n    return {\n      user,\n      tokens: {\n        accessToken: code,\n      },\n    };\n  }\n\n  setCallbackCookieHeader(_cookieHeader: string | null): void {\n    // No-op: we don't use PKCE cookies — the shared API handles the full OAuth flow\n  }\n\n  getLoginCookies(): string[] | undefined {","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/auth/studio/src/index.ts#L218-L254","documentation":"During the SSO/OAuth callback flow, handleCallback exchanges the authorization code for a session and verifies the session cookie. When verifySessionCookie returns null the callback cannot establish a valid user session, so it throws 'Session validation failed' and the sign-in flow aborts with a 500.","triggerScenarios":"A user hits the /auth/callback endpoint with a code that fails verification: expired or already-used authorization code, forged/malformed code, or the shared API URL / cookie state being inconsistent so the session can't be decrypted or validated.","commonSituations":"User bookmarked or reloaded the callback URL (code reuse); clock skew between server and auth provider; mismatched cookie secrets across deployed instances; user hitting the callback directly without completing the SSO flow.","solutions":["Have the user restart the sign-in flow from the beginning (fresh authorization code)","Verify session/cookie secrets are identical across all server instances and match the SSO provider config","Check the logged context (sharedApiUrl, codeLength) for URL/config mismatches","Wrap the callback handler to return a redirect to the login page with an error message instead of an unhandled 500"],"exampleFix":"// before\nconst user = await this.verifySessionCookie(code);\nif (!user) throw new Error('Session validation failed');\n// after (caller-side handling)\ntry {\n  const user = await auth.handleCallback(req);\n} catch (e) {\n  if (e.message === 'Session validation failed') {\n    return res.redirect('/login?error=session_expired');\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"function validateCallbackRequest(req) {\n  const code = new URL(req.url, 'http://x').searchParams.get('code');\n  if (!code) return { ok: false, reason: 'missing code param' };\n  return { ok: true, code };\n}","typeGuard":"function isCallbackError(e) {\n  return e instanceof Error && e.message === 'Session validation failed';\n}","tryCatchPattern":"try {\n  const session = await auth.handleCallback(req);\n} catch (e) {\n  if (isCallbackError(e)) {\n    return res.redirect('/login?error=session_validation_failed');\n  }\n  throw e;\n}","preventionTips":["Redirect users to login with a friendly error instead of surfacing a raw 500","Ensure session/cookie secrets match across all server instances","Guard against code reuse: never cache or replay callback URLs","Log sharedApiUrl and codeLength (as the library does) to diagnose config drift"],"tags":["auth","sso","session","callback"],"backgroundTag":"session-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}