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

  1. Retry sign-in after confirming the account still exists; if it was deleted, re-register or restore the user.
  2. Investigate the user table for the `identity.userId` to detect data-integrity problems.
  3. 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

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


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/ed9153541ba6cb9f. Report an issue: GitHub.