AssertionError after selecting shipping method

Created on 24 July 2025, 3 months ago

Drupal: 11.2.2
Commerce: 3.1.0
Commerce shipping pickup api: 1.0.x-dev updated 15 Jul 2025

I have one flat rate shipping method and one in-store pickup method. After selecting either of them, I receive an AJAX error with the following message. With the older dev version, I was able to choose a shipping method without any issues.

AssertionError: assert($this->shippingMethod instanceof PickupShippingInterface) in assert() (line 103 of modules/contrib/commerce_shipping_pickup_api/src/Plugin/Commerce/InlineForm/PickupProfile.php).
Drupal\commerce_shipping_pickup_api\Plugin\Commerce\InlineForm\PickupProfile->validateInlineForm(Array, Object) (Line: 145)
Drupal\commerce\Plugin\Commerce\InlineForm\InlineFormBase::runValidate(Array, Object, Array)
call_user_func_array(Array, Array) (Line: 282)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 239)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 239)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object, 'commerce_checkout_flow_multistep_default') (Line: 118)
Drupal\Core\Form\FormValidator->validateForm('commerce_checkout_flow_multistep_default', Array, Object) (Line: 585)
Drupal\Core\Form\FormBuilder->processForm('commerce_checkout_flow_multistep_default', Array, Object) (Line: 321)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 219)
Drupal\Core\Form\FormBuilder->getForm(Object, 'order_information') (Line: 143)
Drupal\commerce_checkout\Controller\CheckoutController->formPage(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 622)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 121)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 183)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 53)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 116)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 90)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 53)
Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 715)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

🐛 Bug report
Status

Active

Version

1.0

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @mydot
  • 🇭🇺Hungary djg_tram

    The validation routine is in fact new but it should still receive a PickupShippingInterface. Do you use one of the published submodules or maybe you created your own? In the second case, could you peek into

    https://git.drupalcode.org/project/commerce_shipping_pickup_api/-/blob/1...

    to see what you get there that makes the assert complain?

  • At first, I tried with my own module. Then I uninstalled it and tried using only the pickup_store submodule. The same problem occurred.

    $this->shippingMethod is a FlatRate shipping method that I selected earlier.

  • 🇭🇺Hungary djg_tram

    Then could you make just one more check with rewriting this condition to:

    if ($this->shippingMethod != NULL && $this->shippingMethod instanceof PickupShippingInterface) {
    // - NULL when going on - validate selection
    // - FALSE when changing address - don't validate, selection is unimportant

    The new $this->shippingMethod->validateForm obviously cannot be called for other methods but this gets called, apparently, not just with our own methods. I suspect this would solve the issue and then I upload the fix.

  • it's working with your changes

  • I noticed another bug with the validation. If I change the shipping method from a previously chosen one to a custom pickup method, the validateForm function is not called. As a result, the customer can proceed with the checkout without providing a shipping address.

  • 🇭🇺Hungary djg_tram

    The whole reason for the validation change was that I'm working on https://www.drupal.org/project/commerce_shipping_pickup_brt and it required modifications to the framework as well. Basically, this provider doesn't return the whole list of pickup points (or shows them all on a map) but requires us to send in a base address first and only returns a set number of pickup points around that address. This means that the submodule has to ask the user for an approximate address first (and, of course, this can be different, doesn't have to be the billing address of the customer).

    I already had the submodule mostly working when, during testing, we found out that various scenarios lead to problems. There are two fields that accept the name and address of the selected pickup point. However, there's a problem: at first, it's obvious to set these fields as #required — if the point isn't selected, this fields are empty, so this stops the user from going forward without a pickup point. However, and this is the problem: if the user has a previously stored address but decides to enter a new one right there, Drupal will not Ajax refresh the pane because the required fields are empty. Contradiction.

    Hence the validation: I tried to make it possible not to rely on the usual Drupal Commerce auto-validation but to make it possible for any submodule to provide its own validation. If you look into them, eg. https://git.drupalcode.org/project/commerce_shipping_pickup_brt/-/blob/1..., yes, they have their own that doesn't rely on #required attributes any more.

    Obviously, it's still problematic but your experience and input comes in handy because, just with this BRT, we're right now experiencing different behavior in two different test sites, and whether it already works correct or not, both should behave at least the same way and they are not, so we're scratching our heads right now. You could provide you rown validation as well but actually, this shouldn't be required, I tried to make sure that this new validation is optional but in no way required, and if you don't need anything special like the BRT submodule, you shouldn't need to worry about it.

    So, to cut it short, if you could just look briefly into your module and see what causes it to miss the validation, maybe to dpm() the values in a few spots, especially around https://git.drupalcode.org/project/commerce_shipping_pickup_api/-/blob/1... to see whether what's there in the comments is alos valid in your particular case, that would really help to sort this out.

  • I am working on a submodule where the customer selects a pickup point on an iframe map, and its details are copied into a hidden field. So for my purposes, it's enough to make that field required or add an element validation.

    I checked the PickupProfiles::validateInlineForm() method. When I choose a shipping method, recalculate_shipping is set to FALSE, so validateForm() is not called. But when I refresh the page or return from the review step, recalculate_shipping is NULL, so the validation is triggered.

  • 🇭🇺Hungary djg_tram

    OK. But, in https://git.drupalcode.org/project/commerce_shipping_pickup_api/-/blob/1..., the base validateForm() is left completely empty, on purpose — I didn't make it abstract like the other two functions, just so that you don't have to provide it, staying optional. So, even if it is triggered, it should do nothing in your case.

    And the previous location, https://git.drupalcode.org/project/commerce_shipping_pickup_api/-/blob/1..., calls the parent function all right. So, right now, I'm still not sure what causes the trouble for you. :-)

  • Now that I’ve added an element validation, everything is working - no issues. I was just expecting validateForm() to be called on every submit. Maybe I misunderstood something. Sorry for the confusion. Bocsi! :)

Production build 0.71.5 2024