eyaltoledano/claude-task-master · error · AuthenticationError

REFRESH_FAILED

REFRESH_FAILED

Error message

Failed to refresh session: ${(error as Error).message}

What it means

SupabaseClient.refreshSession() wraps any unexpected failure from `supabase.auth.refreshSession()` in an AuthenticationError with code REFRESH_FAILED. Known Supabase auth errors are already converted by toAuthenticationError/isSupabaseAuthError, so this generic wrapper only fires when the refresh fails for a non-auth reason (network failure, unexpected exception, malformed client state). It means the stored refresh token could not be exchanged for a new session.

Source

Thrown at packages/tm-core/src/modules/integration/clients/supabase-client.ts:288

				throw toAuthenticationError(error, 'Failed to refresh session');
			}

			if (session) {
				this.logger.info('Successfully refreshed session');
			}

			return session;
		} catch (error) {
			if (error instanceof AuthenticationError) {
				throw error;
			}

			// Handle raw Supabase auth errors that might be thrown
			if (isSupabaseAuthError(error)) {
				throw toAuthenticationError(error, 'Session refresh failed');
			}

			throw new AuthenticationError(
				`Failed to refresh session: ${(error as Error).message}`,
				'REFRESH_FAILED'
			);
		}
	}

	/**
	 * Get current user from session
	 */
	async getUser(): Promise<User | null> {
		const client = this.getClient();

		try {
			const {
				data: { user },
				error
			} = await client.auth.getUser();

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Check network connectivity / proxy rules so the machine can reach the Supabase project URL.
  2. Call getSession() first; if it returns null the session is gone — re-authenticate via login instead of refreshing.
  3. Sign out and clear the session storage, then perform a fresh login to obtain a new refresh token.
  4. Inspect the wrapped message for the underlying cause (storage adapter, fetch error) and fix that root cause.

Example fix

// before
const session = await client.refreshSession();
// after
try {
  const session = await client.refreshSession();
} catch (e) {
  if (e instanceof AuthenticationError && e.code === 'REFRESH_FAILED') {
    await client.signOut();
    // restart interactive login flow
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// guard: only refresh when a session actually exists
const current = await client.getSession();
if (!current) {
  // no session to refresh — go straight to login
}

Type guard

function hasAuthErrorCode(e: unknown, code: string): e is AuthenticationError {
  return e instanceof AuthenticationError && e.code === code;
}

Try / catch

try {
  const session = await client.refreshSession();
} catch (e) {
  if (e instanceof AuthenticationError && e.code === 'REFRESH_FAILED') {
    await client.signOut();
    // fall back to interactive login
  } else throw e;
}

Prevention

When it happens

Trigger: Calling refreshSession() when client.auth.refreshSession() throws an exception that is neither an AuthenticationError nor a Supabase AuthApiError — e.g. fetch/network failure, storage adapter throwing while reading the refresh token, or a programming error inside the Supabase client.

Common situations: Offline or behind a corporate proxy blocking supabase.co; expired/revoked refresh token paired with a thrown (not error-returned) response; custom storage adapter crashing on read; clock-skew or DNS failures in CI containers.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/0e01dbc421d2b3a1. Report an issue: GitHub.