Stirling-Tools/Stirling-PDF · error · Error

Supabase is not configured. Seat updates are not available.

Error message

Supabase is not configured. Seat updates are not available.

What it means

Thrown by updateEnterpriseSeats when Supabase isn't configured. Enterprise seat changes are confirmed via the manage-billing Supabase edge function (with a new_seat_count body), so without Supabase the operation is unavailable. The guard fails fast with a message naming the unavailable capability (seat updates).

Source

Thrown at frontend/editor/src/proprietary/services/licenseService.ts:528

      console.error("Error resyncing license:", error);
      throw error;
    }
  },

  /**
   * Update enterprise seat count
   * Creates a Stripe billing portal session for confirming seat changes
   * @param newSeatCount - New number of seats
   * @param licenseKey - Current license key for authentication
   * @returns Billing portal URL for confirming the change
   */
  async updateEnterpriseSeats(
    newSeatCount: number,
    licenseKey: string,
  ): Promise<string> {
    // Check if Supabase is configured
    if (!isSupabaseConfigured || !supabase) {
      throw new Error(
        "Supabase is not configured. Seat updates are not available.",
      );
    }

    const baseUrl = window.location.origin;
    const returnUrl = `${baseUrl}/settings/adminPlan?seats_updated=true`;

    const { data, error } = await supabase.functions.invoke("manage-billing", {
      body: {
        return_url: returnUrl,
        license_key: licenseKey,
        self_hosted: true,
        new_seat_count: newSeatCount,
      },
    });

    if (error) {
      throw new Error(`Failed to update seat count: ${error.message}`);

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Gate the seat-count UI on isSupabaseConfigured.
  2. Set VITE_SUPABASE_URL/VITE_SUPABASE_ANON_KEY in the active env layer.
  3. Catch the error and inform the user seat changes aren't available in this mode.

Example fix

// before
const url = await licenseService.updateEnterpriseSeats(newCount, key);

// after
if (!isSupabaseConfigured) {
  showToast(t('license.seatUpdateUnavailable'));
  return;
}
const url = await licenseService.updateEnterpriseSeats(newCount, key);
Defensive patterns

Strategy: validation

Validate before calling

if (!isSupabaseConfigured) {
  showToast(t('license.seatUpdateUnavailable'));
  return;
}

Type guard

export function canUpdateSeats(): boolean {
  return isSupabaseConfigured;
}

Try / catch

try {
  await licenseService.updateEnterpriseSeats(newCount, key);
} catch (e) {
  if (/not configured/i.test(e instanceof Error ? e.message : "")) {
    showToast(t('license.seatUpdateUnavailable'));
  } else throw e;
}

Prevention

When it happens

Trigger: Admin changes seat count in a self-hosted build without Supabase configured; isSupabaseConfigured false; calling updateEnterpriseSeats from a flavor that omits Supabase.

Common situations: Self-hosted deploy missing Supabase env vars; dev run without .env.local keys; the seat-management UI rendered when licensing backend is offline.

Related errors


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