Significant-Gravitas/AutoGPT · error · APIError

FORBIDDEN

FORBIDDEN

Error message

Signups are not allowed.

What it means

An APIError with code FORBIDDEN thrown from a Supabase databaseHooks.user.create.before hook in the frontend auth config (src/lib/auth/auth.ts). The signup gate (signup-gate.ts) checks isSignupAllowed(email, config) for EVERY new user row — email/password signup and first OAuth sign-in alike — and throws when disallowed, using decision.reason or this default. The phrasing is intentionally matched so the frontend isWaitlistError() maps it to the 'not allowed' modal.

Source

Thrown at autogpt_platform/frontend/src/lib/auth/auth.ts:81

}

export const auth = betterAuth({
  baseURL,
  secret: process.env.BETTER_AUTH_SECRET,
  database: authDbPool,
  telemetry: { enabled: false },
  databaseHooks: {
    user: {
      create: {
        // Env-driven signup gate (see signup-gate.ts). Fires for both
        // email/password signup AND a first OAuth sign-in, since both create
        // a user row. Existing users and the SQL data-migration bypass it.
        // The thrown message is phrased so the frontend `isWaitlistError()`
        // maps it to the existing "not allowed" modal.
        before: async (user: { email: string }) => {
          const decision = isSignupAllowed(user.email, readSignupGateConfig());
          if (!decision.allowed) {
            throw new APIError("FORBIDDEN", {
              message: decision.reason ?? "Signups are not allowed.",
            });
          }
        },
      },
      update: {
        // updateUserByEmail (fired when a change-email link is confirmed)
        // runs this hook post-commit; mirror the now-verified email onto the
        // platform User row so notifications/Stripe track the confirmed
        // identity. See email-mirror.ts for the why.
        after: async (user: { id: string; email: string }) => {
          await mirrorVerifiedEmailToPlatformUser(authDbPool, user);
        },
      },
    },
  },
  advanced: {
    database: {

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Check the signup-gate config (env vars read by readSignupGateConfig in signup-gate.ts) — disable the gate or add the email/domain to the allowlist.
  2. Restart the frontend after changing the env vars; the config is read server-side.
  3. If the user SHOULD be allowed, verify the exact email (case, aliases like +tags, OAuth provider email vs allowlisted one).
  4. For data migrations, insert users via SQL (documented bypass) instead of the auth API.

Example fix

# before (frontend/.env)
SIGNUP_ALLOWLIST_ONLY=true

# after — open signups
SIGNUP_ALLOWLIST_ONLY=false
Defensive patterns

Strategy: validation

Validate before calling

import { isSignupAllowed, readSignupGateConfig } from "@/lib/auth/signup-gate";

function checkSignupAllowed(email: string): { allowed: boolean; reason?: string } {
  return isSignupAllowed(email, readSignupGateConfig());
}

Type guard

function isWaitlistError(err: unknown): boolean {
  return (
    err instanceof Error && /signups are not allowed/i.test(err.message)
  );
}

Try / catch

// server action / route handler wrapping supabase.auth.signUp
try {
  await supabase.auth.signUp({ email, password });
} catch (error) {
  if (isWaitlistError(error)) {
    return { error: "Signups are currently restricted. Join the waitlist instead." };
  }
  throw error;
}

Prevention

When it happens

Trigger: A new user completing email/password signup or first OAuth sign-in while the signup gate config disallows it: waitlist mode enabled without the email on the allowlist, allowlist-only mode with an unknown email, or domain-restriction mode with a disallowed domain. Existing users never hit this (their rows already exist); SQL data-migration inserts bypass the hook.

Common situations: Self-hosters leaving waitlist/allowlist enabled after meaning to open signups; SignupRestrictedUntil / allowlist env vars set in .env (see signup-gate.ts config source) that the operator forgot; invited users signing in with a different email than the one allowlisted.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/adeda1a3bc996811. Report an issue: GitHub.