{"record":{"id":"398f91cd37190802","repo":"toeverything/AFFiNE","slug":"sign-up-forbidden-398f91","errorCode":"sign_up_forbidden","errorMessage":"You are not allowed to sign up.","messagePattern":"You are not allowed to sign up\\.","errorType":"exception","errorClass":"SignUpForbidden","httpStatus":403,"severity":"error","filePath":"packages/backend/server/src/plugins/oauth/service.ts","lineNumber":216,"sourceCode":"      provider,\n      externalAccount.id\n    );\n\n    if (connectedAccount) {\n      await this.updateConnectedAccount(connectedAccount, tokens);\n\n      if (\n        !connectedAccount.user.emailVerifiedAt &&\n        externalAccount.email.toLowerCase() ===\n          connectedAccount.user.email.toLowerCase()\n      ) {\n        await this.auth.setEmailVerified(connectedAccount.userId);\n      }\n      return connectedAccount.user;\n    }\n\n    if (!this.config.auth.allowSignupForOauth) {\n      throw new SignUpForbidden();\n    }\n\n    const user = await this.models.user.fulfill(externalAccount.email, {\n      name: externalAccount.name,\n      avatarUrl: externalAccount.avatarUrl,\n    });\n\n    await this.models.user.createConnectedAccount({\n      userId: user.id,\n      provider,\n      providerAccountId: externalAccount.id,\n      accessToken: tokens.accessToken,\n      refreshToken: tokens.refreshToken,\n      expiresAt: tokens.expiresAt,\n    });\n\n    return user;\n  }","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/plugins/oauth/service.ts#L198-L234","documentation":"SignUpForbidden thrown at packages/backend/server/src/plugins/oauth/service.ts:216 when an OAuth identity has no existing connected account and the server has auth.allowSignupForOauth disabled. AFFiNE first tries to match a connected account; only when none exists does it consult the signup flag before creating a user via fulfill(). The error code is sign_up_forbidden (HTTP class action_forbidden).","triggerScenarios":"A brand-new user signs in with Google/GitHub/OIDC on a server where allowSignupForOauth=false; or an existing email-based user tries an OAuth provider they never linked — no connected account exists, so the signup gate applies even though the email is known.","commonSituations":"Self-hosters lock the instance to invited/existing users (allowSignupForOauth=false) and users assume OAuth login is separate from signup; users who registered with email/password try 'Sign in with Google' before linking it in settings; admin disables OAuth signup after rollout.","solutions":["Enable OAuth signup in config (auth.allowSignupForOauth, default true) and restart the server.","Otherwise the user should sign in with their original method (email/password or a previously linked provider).","Existing users can link the provider in user settings so future OAuth sign-ins match a connected account.","Admins can also pre-create accounts so the fulfill() path is never needed."],"exampleFix":"# before\nAFFINE_SERVER_SUB_PATH=... # auth config with signup closed\n# auth.allowSignupForOauth = false\n\n# after (config)\n{\"auth\":{\"allowSignupForOauth\":true}}\n# or via env/config file depending on your deployment, then restart","handlingStrategy":"validation","validationCode":"// Client: only offer SSO 'sign in' when new-user signup is allowed\nconst serverConfig = await fetch('/api/server/info').then(r => r.json());\n// if OAuth signup is disabled, route new users to an invite/existing-account flow first","typeGuard":null,"tryCatchPattern":"try {\n  await oauth.verifyCallback(input);\n} catch (err) {\n  if (err instanceof SignUpForbidden) {\n    // show 'Sign-up is disabled on this server. Sign in with your existing account or ask an admin.'\n  }\n}","preventionTips":["Set auth.allowSignupForOauth deliberately (it defaults to true).","Tell users to link providers in account settings before relying on SSO login when signup is closed.","Surface a clear 'signup disabled' message in the client instead of a generic OAuth failure."],"tags":["oauth","signup","authorization","configuration"],"backgroundTag":"signup-disabled","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}