 <p>Checking for the prior existence of <code>message_id</code> seems to have solved the problem in my particular case:</p> <pre><code>after_commit on: :create do unless self.message_id if email = Mailer.email(self).deliver self.update message_id: email.message_id end end end </code></pre> <p>But I imagine there could be a scenario where I couldn't get away with that, so it'd still be good to understand why an <code>on: :create</code> callback is being called on update.</p>