Stirling-Tools/Stirling-PDF · critical · Error

error.message || Supabase deletion failed

Error message

error.message || Supabase deletion failed

What it means

Thrown by userManagementService.deleteUser() when the delete-user Supabase edge function returns an error object after the target_email was already validated. The error message prioritizes error.message (the Supabase FunctionsError detail) and falls back to a generic string. This is distinct from error 189 which is the self-service path; this is the admin-initiated deletion.

Source

Thrown at frontend/editor/src/saas/services/userManagementService.ts:198

    user: User,
    options?: { notifyUser?: boolean },
  ): Promise<void> {
    if (isSupabaseConfigured && supabase) {
      if (!user.email) {
        throw new Error(
          "Email missing for this user. Please contact support for manual removal.",
        );
      }

      const { error } = await supabase.functions.invoke("delete-user", {
        body: {
          target_email: user.email,
          notify_user: options?.notifyUser ?? true,
        },
      });

      if (error) {
        throw new Error(error.message || "Supabase deletion failed");
      }
      return;
    }
  },

  /**
   * Invite users via email (admin only)
   * Sends comma-separated email addresses, creates accounts with random passwords,
   * and sends invitation emails
   */
  async inviteUsers(data: InviteUsersRequest): Promise<InviteUsersResponse> {
    const formData = new FormData();
    formData.append("emails", data.emails);
    formData.append("role", data.role);
    if (data.teamId) {
      formData.append("teamId", data.teamId.toString());
    }

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Read error.message for the specific edge function error reason
  2. Verify the target user still exists in the Supabase auth users table
  3. Check the delete-user edge function logs for the server-side stack trace
  4. Ensure the edge function has STRIPE_SECRET_KEY and SUPABASE_SERVICE_ROLE_KEY configured
  5. Confirm the admin invoking the deletion has the correct role/permissions
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm the target user still exists before deletion
const { data } = await supabase.auth.admin.getUserById(user.id);
if (!data?.user) {
  showAdminError('This user no longer exists.');
  return;
}

Try / catch

try {
  await deleteUser(user, { notifyUser: true });
  await refreshUserList();
} catch (e) {
  const msg = e instanceof Error ? e.message : 'Deletion failed';
  if (msg.includes('not found')) {
    setAdminError('User not found — they may have already been deleted.');
    await refreshUserList();
  } else {
    setAdminError(msg);
  }
}

Prevention

When it happens

Trigger: The edge function fails after receiving the request — target user not found, admin lacks service-role permissions, Stripe redaction of the target user's subscription fails, or the Supabase admin auth API call errors.

Common situations: Target user was already deleted (race condition); SUPABASE_SERVICE_ROLE_KEY missing or invalid in the edge function; target user has an active Stripe subscription that can't be cancelled; edge function internal error.

Related errors


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