toeverything/AFFiNE · error · WrongSignInCredentials
wrong_sign_in_credentials
wrong_sign_in_credentials
Error message
Wrong user email or password: ${email} What it means
During magic-link send, a user matching the email is found but has disabled=true in the users table. Rather than reveal the account is disabled, the server throws WrongSignInCredentials with the email — the same shape used for invalid credentials — to avoid account enumeration. Category maps to wrong_sign_in_credentials.
Source
Thrown at packages/backend/server/src/core/auth/magic-link.ts:62
const callbackUrlObj = this.url.url(callbackUrl);
const redirectUriInCallback =
callbackUrlObj.searchParams.get('redirect_uri');
if (
redirectUriInCallback &&
!this.url.isAllowedRedirectUri(redirectUriInCallback)
) {
throw new ActionForbidden();
}
const user = await this.models.user.getUserByEmail(email, {
withDisabled: true,
});
if (!user) {
await this.assertSignupAllowed(email);
} else if (user.disabled) {
throw new WrongSignInCredentials({ email });
}
const ttlInSec = 30 * 60;
const { token, expiresAt: tokenExpiresAt } =
await this.models.verificationToken.createWithExpiresAt(
TokenType.SignIn,
email,
ttlInSec
);
const otp = this.crypto.otp();
const { expiresAt: otpExpiresAt } = await this.models.magicLinkOtp.upsert(
email,
otp,
token,
clientNonce
);
View on GitHub (pinned to 26c515e050)
Solutions
- Have an admin re-enable the account (clear the disabled flag) if access should be restored.
- If the user should not have access, treat this as expected and show a generic 'wrong credentials' message to the user.
- Do not attempt to sign up a new account with the same email; the existing disabled record blocks it.
- Audit admin actions / the users table to confirm the disabled flag's intended state.
Defensive patterns
Strategy: try-catch
Type guard
function isWrongSignInCredentials(err: unknown): boolean {
return (
!!err &&
typeof err === 'object' &&
(err as { code?: string }).code === 'wrong_sign_in_credentials'
);
} Try / catch
try {
await magicLink.send(email);
} catch (err) {
if (isWrongSignInCredentials(err)) {
showGenericError('Wrong email or credentials.');
return;
}
throw err;
} Prevention
- Treat wrong_sign_in_credentials as a generic message; do not reveal the account is disabled.
- Surface a clear admin contact path so disabled users can request re-enablement.
- Audit disabled-flag changes in admin tooling.
- Do not allow re-registration of a disabled account's email.
When it happens
Trigger: Calling MagicLinkAuthService.send with an email whose user row exists and disabled=true (set by an admin via disableUser or equivalent). The check happens after callback/redirect validation and after confirming the user exists with withDisabled:true.
Common situations: An admin suspended the user but they still try to sign in via magic link. A disabled account leftover from a data import. Self-hosted ops flipped the disabled flag manually.
Related errors
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/7d190036b2e9d2c1.
Report an issue: GitHub.