mastra-ai/mastra · error · ProviderAuthRequiredError

Failed to refresh the xAI token.

Error message

Failed to refresh the xAI token.

What it means

After validating the 'xai' oauth credential, buildXAIOAuthFetch calls storage.getApiKey('xai') to obtain the access token, refreshing it if expired. If that returns nothing, it throws ProviderAuthRequiredError('Failed to refresh the xAI token.') because the request cannot be authorized.

Source

Thrown at mastracode/sdk/src/providers/xai.ts:54

/**
 * Build a fetch wrapper that authenticates with xAI OAuth.
 * Injects the access token (auto-refreshed by AuthStorage) as a bearer token,
 * preserving non-auth headers from the caller.
 */
export function buildXAIOAuthFetch(opts: { authStorage?: CredentialStore } = {}): typeof fetch {
  return (async (url: string | URL | Request, init?: Parameters<typeof fetch>[1]) => {
    const storage = opts.authStorage ?? getAuthStorage();
    storage.reload();

    const cred = storage.get(XAI_PROVIDER_ID);
    if (!cred || cred.type !== 'oauth') {
      throw new ProviderAuthRequiredError('Not logged in to xAI.');
    }

    // getApiKey() refreshes the access token if it has expired.
    const accessToken = await storage.getApiKey(XAI_PROVIDER_ID);
    if (!accessToken) {
      throw new ProviderAuthRequiredError('Failed to refresh the xAI token.');
    }

    // Preserve existing headers, strip auth-related ones. Explicit init
    // headers override headers carried by an incoming Request.
    const headers = new Headers(url instanceof Request ? url.headers : undefined);
    if (init?.headers) {
      new Headers(init.headers).forEach((value, key) => headers.set(key, value));
    }
    headers.delete('authorization');
    headers.delete('x-api-key');

    headers.set('Authorization', `Bearer ${accessToken}`);

    try {
      return await fetch(url, { ...init, headers });
    } catch (error) {
      if (error && typeof error === 'object') {
        Object.assign(error as Record<string, unknown>, {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Re-run the xAI OAuth login to obtain fresh tokens.
  2. Check network connectivity to the xAI/OAuth token endpoint.
  3. Confirm the stored credential includes refresh token material.
  4. Catch ProviderAuthRequiredError and trigger re-login then retry.

Example fix

// before
const res = await fetchWithOAuth(url, init); // refresh fails, throws
// after
try {
  return await fetchWithOAuth(url, init);
} catch (e) {
  if (e instanceof ProviderAuthRequiredError) await xaiLogin(); // re-auth then retry
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const token = await storage.getApiKey('xai');
if (!token) console.warn('xAI token unavailable; re-login required before requests');

Type guard

null

Try / catch

try {
  return await fetchWithOAuth(url, init);
} catch (e) {
  if (e instanceof ProviderAuthRequiredError && /refresh/.test(e.message)) {
    await xaiLogin(); // refresh token dead; re-auth then retry
    return await fetchWithOAuth(url, init);
  }
  throw e;
}

Prevention

When it happens

Trigger: A request through the xAI OAuth fetch when the stored credential is a valid oauth entry but storage.getApiKey('xai') returns null/undefined — the token refresh failed or no token material is stored.

Common situations: Expired/revoked refresh token; network or proxy failure during the refresh call; credentials file missing the refresh token; clock skew making tokens seem expired; xAI revoking sessions after re-login on another device.

Related errors


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