2

In a Magento 2 store, the checkout breaks when the user successfully logs in. When the user logs in and enters their address info, they receive no shipping quotes, and an error pops up saying "cartId is a required field".

The error is actually misleading: The underlying problem (discovered using xdebug) is that the quote table row for their cart is missing a customer_id. Instead, it has a NULL value for this field.

This means that:

  1. Magento calls this function

    Magento\Quote\Model\ResourceModel\Quote::loadByCustomerId($quote, $customerId)

    * For the purpose of this example, $customerId = 1;

  2. Which runs a query:

    SELECT `quote`.* FROM `quote` WHERE ( `quote`.`customer_id` = 1 ) AND ( store_id IN ( '1' ) ) AND ( is_active = 1 ) ORDER BY `updated_at` DESC LIMIT 1

  3. Of course, nothing is found, so an exception is thrown. The actual error is masked by a catch-all that does nothing -- the same one described in GitHub Issue #9744 } catch (NoSuchEntityException $e) { /* do nothing and just return null */ }

So my question is: Why would the quote not have a customer_id for the quote that the customer had created when adding products to the cart? The products still show up in the right sidebar, so the quote is still attached to their session, but for whatever reason, it lacks their customer_id after they log in.

2

This issue stemmed from an exception being thrown (and masked) deep down in the quote address validation code. When the customer logs in, the quote must be re-saved to set their customer_id, and before saving, it must be validated. If the validation doesn't pass, the quote isn't saved, and so the customer_id field never gets populated, leading to the error mentioned in the question.

This exception was being thrown because there was an include path (/usr/share/php) being added by the php/apache configuration, but due to open_basedir restrictions, it wasn't accessible. As a result, when the auto-loader tried to find the Magento\Framework\Validator\EmailAddress.php class there, it encountered a warning (shown below). Warning: is_readable(): open_basedir restriction in effect. File(/usr/share/php/Zend/Validate/Magento\Framework\Validator\EmailAddress.php) is not within the allowed path(s) : [my paths] in /mnt/www/magento2-documentroot/vendor/magento/zendframework1/library/Zend/Loader.php on line 186' (length=466)

It's still not immediately evident to me why this warning caused an exception to be thrown, but the fix ended up being extremely simple: Just add this line to .htaccess to reset the include path, and prevent the auto-loader from looking in places it has no business looking in:

php_value include_path "."

From what I can tell, Magento 2 is self-contained, and adds its own relevant paths to the include path, so there shouldn't be any need for other include paths. If this is incorrect (or changes at a later date), please let me know in the comments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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