{"record":{"id":"84e404b97d9c8f1b","repo":"mastra-ai/mastra","slug":"session-expired-run-mastra-auth-login","errorCode":null,"errorMessage":"Session expired. Run: mastra auth login","messagePattern":"Session expired\\. Run: mastra auth login","errorType":"exception","errorClass":"Error","httpStatus":401,"severity":"error","filePath":"packages/cli/src/commands/auth/client.ts","lineNumber":40,"sourceCode":" */\nfunction deriveStudioUrl(): string {\n  if (process.env.MASTRA_STUDIO_URL) return process.env.MASTRA_STUDIO_URL;\n  if (MASTRA_PLATFORM_API_URL.includes('staging')) return 'https://studio.staging.mastra.ai';\n  return 'https://studio.mastra.ai';\n}\n\nexport const MASTRA_STUDIO_URL = deriveStudioUrl();\n\nexport const SESSION_EXPIRED_MESSAGE = 'Session expired. Run: mastra auth login';\n\n/**\n * Throw a standardized error for API failures.\n * - 401: \"Session expired\" (authentication failed)\n * - Other: Show the server's error detail or fall back to status code\n */\nexport function throwApiError(message: string, status: number, detail?: string): never {\n  if (status === 401) {\n    throw new Error(SESSION_EXPIRED_MESSAGE);\n  }\n  if (detail) {\n    throw new Error(detail);\n  }\n  throw new Error(`${message}: ${status}`);\n}\n\n/** Best-effort message from platform JSON error bodies (RFC 7807 `detail`, etc.). */\nexport function extractApiErrorDetail(error: unknown): string | undefined {\n  if (!error || typeof error !== 'object') return undefined;\n  const o = error as Record<string, unknown>;\n\n  let detail: string | undefined;\n  if (typeof o.detail === 'string' && o.detail.trim()) detail = o.detail;\n  else if (typeof o.message === 'string' && o.message.trim()) detail = o.message;\n  else if (typeof o.error === 'string' && o.error.trim()) detail = o.error;\n\n  // Validation errors (400) carry the useful part in errors[] — field name plus","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/commands/auth/client.ts#L22-L58","documentation":"throwApiError in packages/cli/src/commands/auth/client.ts converts failed Mastra platform HTTP responses into Error objects. When the platform returns 401 (the stored token is invalid or expired and could not be refreshed), the CLI throws the fixed SESSION_EXPIRED_MESSAGE telling the user to re-authenticate with `mastra auth login`. All API wrappers (fetchOrgs, createToken, listTokensAction, revokeTokenAction, fetchProjects) funnel their failures through this function.","triggerScenarios":"Any CLI command that calls the platform API (fetchOrgs, createToken/list/revoke tokens, fetchProjects) receives HTTP 401 from the server — e.g. the cached access token in ~/.mastra credentials expired and refresh failed before the request, or the server rejected the bearer token.","commonSituations":"Long-lived local credentials that expired; user logged out / revoked sessions on another machine; clock skew invalidating JWTs; server rotated signing keys; MASTRA_API_TOKEN env var set to an old revoked token.","solutions":["Run `mastra auth login` to obtain fresh credentials.","If using MASTRA_API_TOKEN, generate a new token in the Mastra platform dashboard and replace the env var value.","Check system clock accuracy (JWT validation fails on skew) with `timedatectl` or equivalent.","Delete the stale credentials file and log in again from scratch."],"exampleFix":"// before (shell)\nMASTRA_API_TOKEN=old-expired-token mastra deploys list\n// after\nmastra auth login\nmastra deploys list","handlingStrategy":"try-catch","validationCode":"// before calling API\nconst { getToken } = await import('./credentials.js');\nconst token = await getToken(signal, { allowLogin: false }); // throws early if no valid auth\nif (!token) throw new Error('Run `mastra auth login` first');","typeGuard":"function isAuthError(err: unknown, status?: number): boolean {\n  return err instanceof Error &&\n    (err.message.includes('Session expired') || status === 401);\n}","tryCatchPattern":"try {\n  await fetchOrgs(token);\n} catch (err) {\n  if (isAuthError(err)) {\n    console.error('Session expired. Run: mastra auth login');\n    process.exitCode = 1;\n    return;\n  }\n  throw err;\n}","preventionTips":["Refresh credentials proactively (`mastra auth login`) before long automation runs.","Prefer MASTRA_API_TOKEN for machine environments and rotate it on a schedule.","Check token validity early in scripts with a cheap authenticated call before expensive operations.","Keep system clocks synced (NTP) so JWT validation does not spuriously fail."],"tags":["cli","auth","http-401","session"],"backgroundTag":"jwt-token-expired","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}