{"action":"opened","issue":{"url":"https://api.github.com/repos/sequelize/sequelize/issues/4325","labels_url":"https://api.github.com/repos/sequelize/sequelize/issues/4325/labels{/name}","comments_url":"https://api.github.com/repos/sequelize/sequelize/issues/4325/comments","events_url":"https://api.github.com/repos/sequelize/sequelize/issues/4325/events","html_url":"https://github.com/sequelize/sequelize/issues/4325","id":100919515,"number":4325,"title":"validationHooks run twice","user":{"login":"giannico","id":821447,"avatar_url":"https://avatars.githubusercontent.com/u/821447?v=3","gravatar_id":"","url":"https://api.github.com/users/giannico","html_url":"https://github.com/giannico","followers_url":"https://api.github.com/users/giannico/followers","following_url":"https://api.github.com/users/giannico/following{/other_user}","gists_url":"https://api.github.com/users/giannico/gists{/gist_id}","starred_url":"https://api.github.com/users/giannico/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/giannico/subscriptions","organizations_url":"https://api.github.com/users/giannico/orgs","repos_url":"https://api.github.com/users/giannico/repos","events_url":"https://api.github.com/users/giannico/events{/privacy}","received_events_url":"https://api.github.com/users/giannico/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-08-14T02:55:38Z","updated_at":"2015-08-14T02:55:38Z","closed_at":null,"body":"I have a model ```Account```, which represents a user's account in a system. One of the fields is a password, and I have a business scenario where the user's plaintext password should be restricted to 6 - 20 characters. I'm using model validation for this requirement:\r\n\r\n```\r\npassword: {\r\n    field: 'password',\r\n    type: DataTypes.TEXT,\r\n    allowNull: false,\r\n    validate: {\r\n        len: {\r\n            args: [6, 20],\r\n            msg: 'must be between 6 and 20 characters.'\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nI'm using the beforeCreate hook to swap out the plaintext password on the model instance, with a hashed password:\r\n\r\n```\r\nbeforeCreate: function(account, options, fn) {\r\n    utils.auth.hash(account.password).\r\n        then(function(hashedPassword) {\r\n            account.password = hashedPassword;\r\n            fn(null, account);\r\n        }).catch(function(err) {\r\n            fn(err, null);\r\n        });\r\n}\r\n```\r\n\r\nThis has worked well for me so far, create works fine. I just implemented the password update feature, however, and I'm finding that model validation is occurring twice, once before the ```beforeUpdate``` hook, and once after it. With the hooks defined as follows:\r\n\r\n```\r\nhooks: {\r\n    beforeValidate: function() {\r\n        console.log('before validate');\r\n    },\r\n    afterValidate: function() {\r\n        console.log('after validate');\r\n    },\r\n    beforeUpdate: function(account, options, fn) {\r\n        console.log('before update');\r\n        // hash the password\r\n        // account.password = hashedPassword;\r\n        return fn(null, account);\r\n    }\r\n}\r\n```\r\n\r\nUpon saving the model (via the instance ```save()``` method),\r\n\r\nMy console prints:\r\n\r\n```\r\nbefore validate\r\nafter validate\r\nbefore update\r\nbefore validate\r\nafter validate\r\n```\r\n\r\nAs a result, the second set of validation is failing, because the hashed password is set at that point, which exceeds the 20 character validation length. This was not the behavior I expected, am I misinterpreting the way the hooks should work in this scenario?"}}