Run validation callback before ajax The submit element on my form uses an ajax callback which sends out an email.

I have a validation callback which I've added to this form, but it gets run after the ajax callback and so the email will be sent out even if the form doesn't validate.

I can't add the validation to the ajax callback itself because it gets used on lots of other forms on my site.

Is there any way to run my validation callback before ajax is run?
Actually, you will pass through your validateForm() method, whether you are using Ajax or not.

In the validateForm(), you have to set the appropriate errors on your fields which do not validate.
Then, as Charles Bamford stated, you need to handle the error management in your submit callback.

So basically, you would end up with some kind of the following structure:

public function buildForm(array $form, FormStateInterface $form_state) {
  $form['#prefix'] = '&lt;div id="my-ajax-target-element"&gt;&lt;/div&gt;

  $form['my_field'] = [
    '#type' =&gt; 'textfield',
    '#title' =&gt; $this-&gt;t('My field title'),
  ];
  $form['submit'] = [
    '#type' =&gt; 'submit',
    '#value' =&gt; $this-&gt;t('Submit'),
    '#ajax' =&gt; [
      'callback' =&gt; '::myAjaxCallback',
      'wrapper' =&gt; 'my-ajax-target-element',
      'method' =&gt; 'replace',
    ],
 ];

 return $form;

}

public function validateForm(array &amp;$form, FormStateInterface $form_state) {
  $values = $form_state-&gt;getValues();
  // I set error on my field here, but due to Ajax, the display
  // of error messages will be handled in the Ajax callback
  if($values['my_field'] != 'my expected value') {
    $form_state-&gt;setErrorByName('my_field', $this-&gt;t('This is my error message'));
  }
}

public function myAjaxCallback(array &amp;$form, FormStateInterface $form_state) {
  $response = new AjaxResponse();
  // If $form_state contains errors, populate the ajaxResponse content with the error messages
  if($form_state-&gt;hasAnyErrors()) {
    $errors = $form_state-&gt;getErrors();
    $command_content = $errors['my_field'];
  }
  else {
    // Happily proceed to the submission of your form
  }

  $response-&gt;addCommand(new HtmlCommand('#my-ajax-target-element', $command_content));
  return $response;
}