toeverything/AFFiNE · critical · SignUpForbidden
sign_up_forbidden
sign_up_forbidden
Error message
sign up helper is forbidden for non-test environment
What it means
Thrown by AuthService.signUp, an explicitly @deprecated test-only helper, when invoked outside the test environment (env.testing is false). Category 'action_forbidden', code 'sign_up_forbidden'. The check exists so this shortcut (which bypasses invitations, verification, and rate limiting) can never leak into production.
Source
Thrown at packages/backend/server/src/core/auth/service.ts:84
async onApplicationBootstrap() {
if (env.dev) {
await createDevUsers(this.models, this.entitlement);
}
}
async canSignIn(_email: string) {
// may add more sign-in check later
return true;
}
/**
* @deprecated
*
* This is a test only helper to quickly signup a user, do not use in production
*/
async signUp(email: string, password: string): Promise<CurrentUser> {
if (!env.testing) {
throw new SignUpForbidden(
'sign up helper is forbidden for non-test environment'
);
}
return this.models.user
.create({
email,
password,
})
.then(sessionUser);
}
async signIn(email: string, password: string): Promise<CurrentUser> {
return this.models.user.signIn(email, password).then(sessionUser);
}
async verifyPassword(
email: string,View on GitHub (pinned to 26c515e050)
Solutions
- Replace the signUp call with the real registration path (invitation accept / sign-up mutation) appropriate to the environment.
- If this is genuinely test scaffolding, ensure the process runs with env.testing=true (e.g. NODE_ENV=test) and the config loader exposes it.
- Remove the reference entirely; the method is @deprecated.
Example fix
// before (in a seed script run against staging)
await auth.signUp(user.email, user.password);
// after (use the real resolver or restrict to test)
if (process.env.NODE_ENV === 'test') {
await auth.signUp(user.email, user.password);
} else {
throw new Error('Use the invite/sign-up mutation in non-test envs');
} Defensive patterns
Strategy: validation
Validate before calling
import { env } from '../../base/env';
function assertTestEnvForSignUp(): void {
if (!env.testing) {
throw new Error('auth.signUp is a test-only helper; use the real sign-up/invitation flow.');
}
}
assertTestEnvForSignUp();
await auth.signUp(email, password); Type guard
function isTestEnv(): boolean {
return Boolean(env.testing);
} Prevention
- Treat auth.signUp as test-only; grep the codebase for references before any non-test deploy.
- Gate seed/migration scripts on NODE_ENV === 'test'.
- Prefer the invitation or public sign-up mutation for any non-test registration.
When it happens
Trigger: Calling AuthService.signUp(email, password) (service.ts:78-86) in any process where env.testing !== true. The guard is the very first statement, so any non-test caller fails immediately.
Common situations: A developer copied test seed logic into a script/migration/seeder that runs against a non-test database; a feature flag or env mislabel that left signUp referenced in production code paths; an e2e harness pointed at a staging env that does not set NODE_ENV=test.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- action_forbidden
- Invalid rowId
- Invalid config for module [${module}] with key [${key}] Valu
- action_forbidden
- unsupported_client_version
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/8c1e78bd9105d225.
Report an issue: GitHub.