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
- Gate the seat-count UI on isSupabaseConfigured.
- Set VITE_SUPABASE_URL/VITE_SUPABASE_ANON_KEY in the active env layer.
- 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
- Gate the seat-management UI on isSupabaseConfigured.
- Set Supabase env vars where seat management is expected.
- Hide the action in flavors that omit Supabase.
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
- Supabase is not configured. Billing portal is not available.
- Failed to update seat count: ${error.message}
- No billing portal URL returned
- Supabase is not configured. Please use static plans instead.
- Supabase is not configured. Checkout is not available.
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/f4a0a7dc2886952c.
Report an issue: GitHub.