Stirling-Tools/Stirling-PDF · error · StripeFunctionError

Edge function ${name} failed

Error message

Edge function ${name} failed

What it means

Fallback message in invoke() when supabase.functions.invoke returns an error whose .message is falsy. The edge function failed, but the error object carried no human-readable message, so the helper substitutes a generic description naming the failed function.

Source

Thrown at frontend/editor/src/portal/billing/stripe.ts:80

  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> {
  ensureSaasSupabase();
  const supabase = getSupabaseClient();
  if (!supabase) {
    throw new StripeFunctionError(
      "SaaS Supabase not configured — set VITE_SUPABASE_URL.",
      "unconfigured",
    );

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Inspect the full StripeFunctionError in dev tools — the underlying FunctionsError often has a code/cause even when message is empty.
  2. Check the edge function logs in the Supabase dashboard for the named function to see the real failure.
  3. Verify network reachability + CORS for the function endpoint.
  4. Upgrade @supabase/supabase-js consistently across the app to avoid error-shape drift.

Example fix

// before
throw new StripeFunctionError(
  error.message ?? `Edge function ${name} failed`,
);

// after — surface more of the underlying error for diagnosis
throw new StripeFunctionError(
  error.message ?? `Edge function ${name} failed (${(error as any).code ?? "no_code"})`,
  (error as { code?: string }).code,
);
Defensive patterns

Strategy: try-catch

Type guard

function isFunctionsError(e: unknown): e is { message?: string; code?: string } {
  return typeof e === "object" && e !== null && "message" in e;
}

Try / catch

try {
  return await invoke("create-checkout-session", body);
} catch (e) {
  if (e instanceof StripeFunctionError) {
    // message is the edge-function error or the generic fallback
    notifications.show({ message: e.message, color: "red" });
  }
  throw e;
}

Prevention

When it happens

Trigger: An edge function invocation rejects with an error object that has no message property (or message === ''). This is the right-hand operand of `error.message ?? fallback`, so it only fires when message is null/undefined.

Common situations: Network/transport-level failures (CORS, DNS, aborted request) where the FunctionsError has a code but no message; a deployed edge function that throws a non-Error value; a Supabase client version that changed the error shape.

Related errors


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