toeverything/AFFiNE · error · WrongSignInCredentials
wrong_sign_in_credentials
wrong_sign_in_credentials
Error message
Wrong user email or password: ${email} What it means
Thrown in `passwordSignIn` after `verifyPassword` succeeded but `models.user.get(identity.userId)` returned null. The password was correct, yet the user row vanished between the credential check and the user fetch. HTTP 400 (invalid_input) with message `Wrong user email or password: <email>` — deliberately ambiguous to avoid leaking whether the account existed.
Source
Thrown at packages/backend/server/src/core/auth/controller.ts:155
credential.email,
credential.callbackUrl,
credential.client_nonce
);
}
}
async passwordSignIn(
req: Request,
res: Response,
email: string,
password: string
) {
const identity = await this.auth.verifyPassword(email, password);
const { exchangeCode } = await this.sessionIssuer.issue(req, res, identity);
const user = await this.models.user.get(identity.userId);
if (!user) {
throw new WrongSignInCredentials({ email });
}
res.status(HttpStatus.OK).send({
...sessionUser(user),
exchangeCode,
} satisfies SignInResponse);
}
async sendMagicLink(
req: Request,
res: Response,
email: string,
callbackUrl = '/magic-link',
clientNonce?: string
) {
const payload = await this.magicLink.send(email, callbackUrl, clientNonce, {
source: getAbuseRequestSource(req, this.config),
});
res.status(HttpStatus.OK).send(payload);View on GitHub (pinned to 26c515e050)
Solutions
- Retry sign-in after confirming the account still exists; if it was deleted, re-register or restore the user.
- Investigate the user table for the `identity.userId` to detect data-integrity problems.
- If this floods logs, look for deletion/purge jobs running at the same time as auth traffic.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await passwordSignIn(req, res, email, password);
} catch (e) {
if (e.code === 'wrong_sign_in_credentials') {
// do NOT reveal whether the account was deleted; treat as bad credentials
showFormError('Wrong email or password.');
} else throw e;
} Prevention
- Treat this error exactly like wrong-password on the client (same UX).
- Investigate if it spikes — indicates account deletion racing with auth or data loss.
- Audit purge/delete jobs for races against active sign-in.
When it happens
Trigger: The user account is deleted (or hard-purged) in the narrow window between `models.user.signIn` resolving and `models.user.get` running, or a data-integrity issue leaves a credential record pointing at a non-existent user.
Common situations: Account deletion racing with a concurrent sign-in attempt, a GDPR purge job running mid-session, or a partially failed migration that dropped user rows but kept credentials.
Related errors
- auth_session_temporarily_unavailable
- action_forbidden
- authentication_required
- invalid_auth_state
- authentication_required
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/ed9153541ba6cb9f.
Report an issue: GitHub.