{"record":{"id":"f6d6c7b41c7af3f6","repo":"mastra-ai/mastra","slug":"session-expired-run-mastra-auth-login-interacti","errorCode":null,"errorMessage":"Session expired. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.","messagePattern":"Session expired\\. Run `mastra auth login` interactively or set MASTRA_API_TOKEN\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/auth/credentials.ts","lineNumber":362,"sourceCode":"  if (!creds) {\n    if (options.allowLogin === false || !isInteractive()) {\n      throw new Error('Not logged in. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.');\n    }\n    const newCreds = await login(signal, options);\n    return newCreds.token;\n  }\n\n  // Try a quick verify to see if the token is still valid.\n  if (await verifyToken(creds.token, signal)) return creds.token;\n  signal?.throwIfAborted();\n\n  // Token might be expired — attempt refresh\n  const refreshed = await tryRefreshToken(creds, signal);\n  if (refreshed) return refreshed;\n  signal?.throwIfAborted();\n\n  if (options.allowLogin === false || !isInteractive()) {\n    throw new Error('Session expired. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.');\n  }\n  const newCreds = await login(signal, options);\n  return newCreds.token;\n}\n\n/**\n * Validate that the user has access to the specified organization.\n * Throws if the org is not in the user's org list.\n */\nexport async function validateOrgAccess(token: string, orgId: string): Promise<void> {\n  const { fetchOrgs } = await import('./api.js');\n  const orgs = await fetchOrgs(token);\n  const hasAccess = orgs.some(o => o.id === orgId);\n  if (!hasAccess) {\n    throw new Error(`No access to organization ${orgId}. Run: mastra auth orgs`);\n  }\n}\n","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/commands/auth/credentials.ts#L344-L380","documentation":"getToken verifies the stored token against the platform; if the quick verify fails it attempts tryRefreshToken. When refresh also fails and interactive re-login is unavailable (allowLogin === false or non-TTY), it throws this error: the stored session is definitively expired and the CLI cannot silently recover it.","triggerScenarios":"getToken finds stored credentials, the token-validity verify fails (expired/revoked), tryRefreshToken returns falsy (refresh token also expired/rejected or network failure), and options.allowLogin === false or isInteractive() is false.","commonSituations":"Long-unused CLI session whose access and refresh tokens both expired; CI reusing a cached credentials directory with a stale session; token revoked by logging out on another device; running non-interactively via scripts/pipes so browser login cannot launch.","solutions":["Run `mastra auth login` interactively to establish a fresh session.","For CI/non-interactive use, set MASTRA_API_TOKEN to a current token instead of relying on stored credentials.","Delete the stale credentials file and log in again if refresh keeps failing.","Check network reachability to the auth service if refresh should have worked."],"exampleFix":"// before\ncat script.sh  # pipes output, non-TTY -> Error: Session expired...\n// after\nmastra auth login   # refresh credentials interactively\n./script.sh         # or export MASTRA_API_TOKEN=... in CI","handlingStrategy":"validation","validationCode":"const { loadCredentials, tryRefreshToken } = await import('./credentials.js');\nconst creds = await loadCredentials();\nif (!process.env.MASTRA_API_TOKEN && creds && !(await tryRefreshToken(creds)) && !isTTY()) {\n  throw new Error('Stored session expired; run `mastra auth login` or set MASTRA_API_TOKEN');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const token = await getToken(signal, { allowLogin: false });\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Session expired')) {\n    console.error('Re-authenticate: `mastra auth login` (interactive) or set MASTRA_API_TOKEN.');\n    process.exitCode = 1;\n    return;\n  }\n  throw err;\n}","preventionTips":["Rotate to MASTRA_API_TOKEN for automation instead of relying on refreshable browser sessions.","Re-run `mastra auth login` when returning to a project after long gaps.","Refresh credentials before long CI jobs that reuse cached credentials directories.","Watch for session revocation events (logging out elsewhere) that invalidate stored refresh tokens."],"tags":["cli","auth","session-expired","refresh-token","non-interactive"],"backgroundTag":"jwt-token-expired","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}