{"record":{"id":"13168828d9a8cbf8","repo":"immich-app/immich","slug":"wrong-password","errorCode":null,"errorMessage":"Wrong password","messagePattern":"Wrong password","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/auth.service.ts","lineNumber":132,"sourceCode":"      throw new BadRequestException('Invalid logout token: it must contain either a sub or a sid claim');\n    }\n\n    const deletedSessionIds = await this.sessionRepository.invalidateOAuth({\n      oauthSid: claims.sid,\n      oauthId: claims.sub,\n    });\n\n    for (const sessionId of deletedSessionIds) {\n      await this.eventRepository.emit('SessionDelete', { sessionId });\n    }\n  }\n\n  async changePassword(auth: AuthDto, dto: ChangePasswordDto): Promise<UserAdminResponseDto> {\n    const { password, newPassword } = dto;\n    const user = await this.userRepository.getForChangePassword(auth.user.id);\n    const isValid = this.validateSecret(password, user.password);\n    if (!isValid) {\n      throw new BadRequestException('Wrong password');\n    }\n\n    const hashedPassword = await this.cryptoRepository.hashBcrypt(newPassword, SALT_ROUNDS);\n\n    const updatedUser = await this.userRepository.update(user.id, { password: hashedPassword });\n\n    await this.eventRepository.emit('AuthChangePassword', {\n      userId: user.id,\n      currentSessionId: auth.session?.id,\n      invalidateSessions: dto.invalidateSessions,\n    });\n\n    return mapUserAdmin(updatedUser);\n  }\n\n  async setupPinCode(auth: AuthDto, { pinCode }: PinCodeSetupDto) {\n    const user = await this.userRepository.getForPinCode(auth.user.id);\n    if (!user) {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/auth.service.ts#L114-L150","documentation":"Thrown by AuthService.changePassword (POST /auth/change-password) when validateSecret(password, user.password) fails, i.e. the supplied current password does not match the stored bcrypt hash. The user is fetched via getForChangePassword(auth.user.id) so it always exists; only the current-password check can fail, yielding 400 BadRequest 'Wrong password'.","triggerScenarios":"POST /auth/change-password where the 'password' (current) field is incorrect; user changed password elsewhere and the cached credential is stale; password field order swapped with newPassword in the request body.","commonSituations":"User mistypes the current password; client sends fields in the wrong order (newPassword in the password slot); concurrent password change invalidating the old password.","solutions":["Confirm the current password is correct (re-enter, check caps).","Ensure the request body maps password -> current and newPassword -> new exactly as the DTO expects.","If forgotten, use the admin reset / forgot-password flow instead of change-password."],"exampleFix":"// before\nawait api.post('/auth/change-password', { password: newPassword, newPassword: currentPassword });\n\n// after\nawait api.post('/auth/change-password', { password: currentPassword, newPassword });","handlingStrategy":"try-catch","validationCode":"// Map fields exactly as the DTO expects; validate non-empty.\nif (!dto.password || !dto.newPassword) {\n  throw new Error('Both current and new password are required.');\n}\nif (dto.password === dto.newPassword) {\n  throw new Error('New password must differ from the current password.');\n}\nawait api.post('/auth/change-password', { password: dto.password, newPassword: dto.newPassword });","typeGuard":null,"tryCatchPattern":"try {\n  await api.post('/auth/change-password', { password, newPassword });\n} catch (e) {\n  if (e.response?.status === 400 && /wrong password/i.test(e.response?.data?.message)) {\n    showCurrentPasswordError();\n  } else throw e;\n}","preventionTips":["Keep field order explicit: password = current, newPassword = new.","Confirm the current password before submit; offer reset if forgotten.","Beware concurrent password changes invalidating the old password."],"tags":["auth","password","validation","credentials"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}