mastra-ai/mastra · error · Error

Session expired. Run `mastra auth login` interactively or se

Error message

Session expired. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.

What it means

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.

Source

Thrown at packages/cli/src/commands/auth/credentials.ts:362

  if (!creds) {
    if (options.allowLogin === false || !isInteractive()) {
      throw new Error('Not logged in. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.');
    }
    const newCreds = await login(signal, options);
    return newCreds.token;
  }

  // Try a quick verify to see if the token is still valid.
  if (await verifyToken(creds.token, signal)) return creds.token;
  signal?.throwIfAborted();

  // Token might be expired — attempt refresh
  const refreshed = await tryRefreshToken(creds, signal);
  if (refreshed) return refreshed;
  signal?.throwIfAborted();

  if (options.allowLogin === false || !isInteractive()) {
    throw new Error('Session expired. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.');
  }
  const newCreds = await login(signal, options);
  return newCreds.token;
}

/**
 * Validate that the user has access to the specified organization.
 * Throws if the org is not in the user's org list.
 */
export async function validateOrgAccess(token: string, orgId: string): Promise<void> {
  const { fetchOrgs } = await import('./api.js');
  const orgs = await fetchOrgs(token);
  const hasAccess = orgs.some(o => o.id === orgId);
  if (!hasAccess) {
    throw new Error(`No access to organization ${orgId}. Run: mastra auth orgs`);
  }
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Run `mastra auth login` interactively to establish a fresh session.
  2. For CI/non-interactive use, set MASTRA_API_TOKEN to a current token instead of relying on stored credentials.
  3. Delete the stale credentials file and log in again if refresh keeps failing.
  4. Check network reachability to the auth service if refresh should have worked.

Example fix

// before
cat script.sh  # pipes output, non-TTY -> Error: Session expired...
// after
mastra auth login   # refresh credentials interactively
./script.sh         # or export MASTRA_API_TOKEN=... in CI
Defensive patterns

Strategy: validation

Validate before calling

const { loadCredentials, tryRefreshToken } = await import('./credentials.js');
const creds = await loadCredentials();
if (!process.env.MASTRA_API_TOKEN && creds && !(await tryRefreshToken(creds)) && !isTTY()) {
  throw new Error('Stored session expired; run `mastra auth login` or set MASTRA_API_TOKEN');
}

Try / catch

try {
  const token = await getToken(signal, { allowLogin: false });
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Session expired')) {
    console.error('Re-authenticate: `mastra auth login` (interactive) or set MASTRA_API_TOKEN.');
    process.exitCode = 1;
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/f6d6c7b41c7af3f6. Report an issue: GitHub.