Stirling-Tools/Stirling-PDF · error · Error

Supabase is not configured

Error message

Supabase is not configured

What it means

Thrown by signInAnonymously() in the proprietary Supabase client wrapper when the shared module-level client is still null. The client is created lazily via configureSupabase(); until that runs, getSupabaseClient() returns null by design so hosts that never need Supabase (e.g. the portal in Spring mode) don't pull it into the session. Anonymous sign-in is only valid against a live Supabase backend, so the guard fails fast instead of dereferencing null.

Source

Thrown at frontend/editor/src/proprietary/auth/supabase/supabaseClient.ts:49

    auth: {
      persistSession: config.authOptions?.persistSession ?? true,
      autoRefreshToken: config.authOptions?.autoRefreshToken ?? true,
      detectSessionInUrl: config.authOptions?.detectSessionInUrl ?? true,
    },
  });
  return client;
}

/** The configured Supabase client, or null if not configured. */
export function getSupabaseClient(): SupabaseClient | null {
  return client;
}

/** Anonymous (guest) sign-in. Throws if Supabase is not configured. */
export async function signInAnonymously() {
  const supabase = getSupabaseClient();
  if (!supabase) {
    throw new Error("Supabase is not configured");
  }
  return supabase.auth.signInAnonymously();
}

export const isUserAnonymous = (user: { is_anonymous?: boolean } | null) => {
  return user?.is_anonymous === true;
};

/** Fetch the current Supabase user, or null when unauthenticated/unconfigured. */
export async function getCurrentUser() {
  const supabase = getSupabaseClient();
  if (!supabase) return null;
  const {
    data: { user },
  } = await supabase.auth.getUser();
  return user;
}

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Call configureSupabase({url, key}) during app startup (typically in the unified auth provider) before any guest/anonymous sign-in is possible.
  2. Verify VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in the active .env layer (frontend/editor/.env plus the mode-specific file) and not just in a .local you forgot to commit for CI.
  3. Gate the anonymous-sign-in UI on a flag that is only true once Supabase is confirmed configured (e.g. isSupabaseConfigured), so the button can't be clicked in Spring mode.
  4. If the portal is intentionally Spring-only, remove the code path or branch it so signInAnonymously is never reached.

Example fix

// before
await signInAnonymously(); // throws if never configured

// after
const client = getSupabaseClient();
if (!client) {
  throw new Error("Guest sign-in requires Supabase; enable it in Settings > Auth.");
}
await signInAnonymously();
Defensive patterns

Strategy: validation

Validate before calling

import { getSupabaseClient } from "@app/auth/supabase/supabaseClient";

const client = getSupabaseClient();
if (!client) {
  // don't call signInAnonymously; show 'guest sign-in unavailable'
}

Type guard

export function canSignInAnonymously(): boolean {
  return getSupabaseClient() !== null;
}

Try / catch

try {
  await signInAnonymously();
} catch (e) {
  if (/not configured/i.test(e instanceof Error ? e.message : "")) {
    showGuestSignInUnavailable();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling signInAnonymously() before any configureSupabase({url,key}) call; calling it in a Spring-auth build where the unified auth provider was never wired to Supabase; calling it during SSR or before the auth bootstrap effect has run.

Common situations: Missing VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY env vars so the bootstrap skips configureSupabase; running the proprietary build in a flavor (core/desktop) that doesn't initialize the Supabase path; a race where a guest-login button renders before the auth provider's init effect.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/97ba4e4978afc035. Report an issue: GitHub.