I am trying to collect additional information on checkout to add to the order. I have added new fields to the order entity and then used hook_form_commerce_checkout_flow_multistep_default_alter to add "fake" fields to the order_information form. Then, using hook_entity_presave(), I take the values from the fake fields and set the real order fields. This all works as expected.

As some of these fake fields are conditionally required to be entered, I am trying to add a validate function. In the form alter I have added $form['actions']['next']['#submit'][] = '_altpay_form_validate'; and for that function I have:

function _altpay_form_validate(&$form, $form_state) {
  $who_paying = $form_state->getValue('altpay');
  if (!$who_paying) {
    $form_state->setErrorByName('altpay', t('You must select who is paying for this order.'));

Calling setErrorByName() crashes with the following exception.

LogicException: Form errors cannot be set after form validation has finished.

I tried setting Validation Complete to FALSE and then setErrorByName() no longer crashes, but also does not prevent form submission.

I suspect this has something to do with the multi-step nature of this form.

Do you have any hint on what I am missing?

1 Answer 1


$form['actions']['next']['#submit'][] = '_altpay_form_validate';

You're actually adding it to the submit function. Which makes sense the errors that you're seeing since it's too late to do any form validation here.

Needs to be:

$form['actions']['next']['#validate'][] = '_altpay_form_validate';
  • 1
    Wow, clearly I have working too much. Thanks.
    – liquidcms
    Oct 26, 2023 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.