{"record":{"id":"ed9153541ba6cb9f","repo":"toeverything/AFFiNE","slug":"wrong-sign-in-credentials","errorCode":"wrong_sign_in_credentials","errorMessage":"Wrong user email or password: ${email}","messagePattern":"Wrong user email or password: (.+?)","errorType":"exception","errorClass":"WrongSignInCredentials","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/core/auth/controller.ts","lineNumber":155,"sourceCode":"        credential.email,\n        credential.callbackUrl,\n        credential.client_nonce\n      );\n    }\n  }\n\n  async passwordSignIn(\n    req: Request,\n    res: Response,\n    email: string,\n    password: string\n  ) {\n    const identity = await this.auth.verifyPassword(email, password);\n\n    const { exchangeCode } = await this.sessionIssuer.issue(req, res, identity);\n    const user = await this.models.user.get(identity.userId);\n    if (!user) {\n      throw new WrongSignInCredentials({ email });\n    }\n    res.status(HttpStatus.OK).send({\n      ...sessionUser(user),\n      exchangeCode,\n    } satisfies SignInResponse);\n  }\n\n  async sendMagicLink(\n    req: Request,\n    res: Response,\n    email: string,\n    callbackUrl = '/magic-link',\n    clientNonce?: string\n  ) {\n    const payload = await this.magicLink.send(email, callbackUrl, clientNonce, {\n      source: getAbuseRequestSource(req, this.config),\n    });\n    res.status(HttpStatus.OK).send(payload);","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/core/auth/controller.ts#L137-L173","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await passwordSignIn(req, res, email, password);\n} catch (e) {\n  if (e.code === 'wrong_sign_in_credentials') {\n    // do NOT reveal whether the account was deleted; treat as bad credentials\n    showFormError('Wrong email or password.');\n  } else throw e;\n}","preventionTips":["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."],"tags":["authentication","sign-in","race-condition","data-integrity"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}