Stirling-Tools/Stirling-PDF · error · StripeFunctionError
unconfigured
unconfigured
Error message
SaaS Supabase not configured — set VITE_SUPABASE_URL.
What it means
Thrown by the invoke() helper used by all Stripe edge-function calls. ensureSaasSupabase() runs first (asserting SaaS mode), then getSupabaseClient() is expected to return a configured client. If it returns null — meaning VITE_SUPABASE_URL was never provided to the build — the helper throws a StripeFunctionError with code "unconfigured" before attempting any network call.
Source
Thrown at frontend/editor/src/portal/billing/stripe.ts:73
portal_url?: string;
already_subscribed?: boolean;
error?: string;
}
interface PortalResponse {
success: boolean;
url?: string;
error?: string;
}
async function invoke<T>(
name: string,
body: Record<string, unknown>,
): Promise<T> {
ensureSaasSupabase();
const supabase = getSupabaseClient();
if (!supabase) {
throw new StripeFunctionError(
"SaaS Supabase not configured — set VITE_SUPABASE_URL.",
"unconfigured",
);
}
const { data, error } = await supabase.functions.invoke<T>(name, { body });
if (error) {
throw new StripeFunctionError(
error.message ?? `Edge function ${name} failed`,
);
}
if (data == null) {
throw new StripeFunctionError(`Edge function ${name} returned no data`);
}
return data;
}
/** Call a SECURITY DEFINER public.* RPC with the admin's JWT (same client as {@link invoke}). */
async function rpc<T>(fn: string, args: Record<string, unknown>): Promise<T> {View on GitHub (pinned to 9ef20dcab8)
Solutions
- Set VITE_SUPABASE_URL (and VITE_SUPABASE_ANON_KEY) in the SaaS env file and restart the dev server so Vite re-reads env.
- Run in SaaS mode: `task frontend:dev` with the saas flavor / MODE=saas, or `task frontend:prepare MODE=saas` to create .env.saas.local.
- Confirm the variable is committed in frontend/editor/.env.saas (not only in an uncommitted .local that the build does not load).
- If intentional (non-SaaS build), gate the billing UI so these functions are never invoked outside SaaS.
Example fix
# before VITE_SUPABASE_URL= # after (frontend/editor/.env.saas) VITE_SUPABASE_URL=https://your-project.supabase.co VITE_SUPABASE_ANON_KEY=eyJ...
Defensive patterns
Strategy: validation
Validate before calling
function isSaasSupabaseConfigured(): boolean {
return Boolean(
getSupabaseClient() &&
import.meta.env.VITE_SUPABASE_URL,
);
}
if (!isSaasSupabaseConfigured()) {
notifications.show({ message: "Billing requires SaaS Supabase config.", color: "red" });
return;
} Type guard
function hasSupabaseClient(): boolean {
return getSupabaseClient() != null;
} Try / catch
try {
await createCheckoutSession(req);
} catch (e) {
if (e instanceof StripeFunctionError && e.code === "unconfigured") {
notifications.show({ message: "Billing is not configured for this environment.", color: "red" });
} else throw e;
} Prevention
- Commit VITE_SUPABASE_URL + VITE_SUPABASE_ANON_KEY in frontend/editor/.env.saas.
- Run the portal in SaaS mode and verify getSupabaseClient() is non-null before opening billing.
- Hide all billing entry points when getSupabaseClient() returns null.
When it happens
Trigger: Any Stripe billing call (checkout, quote, invoice, portal) is made in an environment where the Supabase client was never instantiated because VITE_SUPABASE_URL is unset/empty. The client singleton is null, so invoke refuses to proceed.
Common situations: Dev started the frontend in core/proprietary/desktop mode instead of saas; .env.saas was not layered (Vite only loaded .env); the env var was renamed/removed; CI built the portal without the SaaS secrets. Note: ensureSaasSupabase usually throws first if you are not in SaaS mode at all, so reaching this null-check typically means you ARE in SaaS mode but the URL env var is missing.
Related errors
- No pricing data returned
- serverMessage || error?.message || Failed to delete account
- Edge function returned no client_secret
- data?.error ?? Portal session response missing url
- Edge function ${name} failed
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/bc4ec6580cd1405d.
Report an issue: GitHub.