4

I've faced an issue in Magento 2.2.9 says "Invalid Customer address id XXXX" randomly for the registered customers on the website.

[2019-08-09 02:44:33] main.CRITICAL: Invalid customer address id XXXXXX {"exception":"[object] (Magento\\Framework\\Exception\\NoSuchEntityException(code: 0): Invalid customer address id 313116 at /vendor/magento/module-quote/Model/QuoteAddressValidator.php:77)"} []

How to fix this issue coming on the Magento 2?

I have checked this further and found that this issue is because of the customer quote which is active and does not have an entry in the quote_address table.

How can we fix this?

Update: This issue is still exists in Magento 2.4.3.

0

5 Answers 5

7

I've checked it further and fixed this issue by overriding Magento's validateForCart function.

/**
 * Validate address to be used for cart.
 *
 * @param CartInterface $cart
 * @param AddressInterface $address
 * @return void
 */
public function validateForCart(CartInterface $cart, AddressInterface $address)
{
    $this->doValidate($address, $cart->getCustomer()->getId() ? $cart->getCustomer()->getId() : null);
}

The issue is with the customer Id passing in the function is null for the customers facing this issue.

EDIT

As per https://github.com/magento/magento2/pull/26637, I've optimized the validateForCart function code.

public function validateForCart(CartInterface $cart, AddressInterface $address): void
{
    $this->doValidate($address, $cart->getCustomer()->getId() ?: null);
}
6
  • Can you please share your full code how did you override the validateForCart ? I have tried with plugin/preference but facing errors. Sep 10, 2019 at 14:04
  • I've done this with preference.
    – Sumit
    Sep 10, 2019 at 15:39
  • Okay thanks I have already done it with preference. Sep 11, 2019 at 10:08
  • @DineshRajput can you share full code? I have this same issue. Nov 5, 2019 at 6:37
  • I have shared my full code @RajeshNagappan Nov 5, 2019 at 10:48
5

I had same issue, used plugin to solve this.

In di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\QuoteAddressValidator">
        <plugin name="disableguestcheck" type="Vendor\Module\Plugin\QuoteAddressValidatorPlugin"/>
    </type>
</config>

In the pLugin Class

<?php
namespace Vendor\Module\Plugin;

use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Api\Data\CartInterface;
use Magento\Quote\Model\QuoteAddressValidator;

class QuoteAddressValidatorPlugin
{
    /**
     * @param QuoteAddressValidator $subject
     * @param CartInterface $cart
     * @param AddressInterface $address
     */
    public function beforeValidateForCart(
        QuoteAddressValidator $subject,
        CartInterface $cart,
        AddressInterface $address
    ): void {
        if ($cart->getCustomer()->getId()) {
            $cart->setCustomerIsGuest(0);
        }
    }
}

One More thing I notice once the plugin is executed It also corrects the customer_is_guest in Quote table in database.

3
4

Below is my code for preference:

app/code/Vendor/Module/etc/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Quote\Model\QuoteAddressValidator" type="Vendor\Module\Model\QuoteAddressValidator" />
</config>

Below is the model to override:

app/code/Vendor/Module/Model/QuoteAddressValidator.php

<?php

namespace Vendor\Module\Model;

use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Api\Data\CartInterface;

/**
 * Quote shipping/billing address validator service.
 *
 * @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
 */
class QuoteAddressValidator extends \Magento\Quote\Model\QuoteAddressValidator
{
/**
 * Address factory.
 *
 * @var \Magento\Customer\Api\AddressRepositoryInterface
 */
protected $addressRepository;

/**
 * Customer repository.
 *
 * @var \Magento\Customer\Api\CustomerRepositoryInterface
 */
protected $customerRepository;

/**
 * @deprecated 101.1.1 This class is not a part of HTML presentation layer and should not use sessions.
 */
protected $customerSession;

/**
 * Constructs a quote shipping address validator service object.
 *
 * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository
 * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository Customer repository.
 * @param \Magento\Customer\Model\Session $customerSession
 */
public function __construct(
    \Magento\Customer\Api\AddressRepositoryInterface $addressRepository,
    \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
    \Magento\Customer\Model\Session $customerSession
) {
    $this->addressRepository = $addressRepository;
    $this->customerRepository = $customerRepository;
    $this->customerSession = $customerSession;
}

/**
 * Validate address.
 *
 * @param AddressInterface $address
 * @param int|null $customerId Cart belongs to
 * @return void
 * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer.
 * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid.
 */
private function doValidate(AddressInterface $address, ?int $customerId): void
{
    //validate customer id
    if ($customerId) {
        $customer = $this->customerRepository->getById($customerId);
        if (!$customer->getId()) {
            throw new \Magento\Framework\Exception\NoSuchEntityException(
                __('Invalid customer id %1', $customerId)
            );
        }
    }

    if ($address->getCustomerAddressId()) {
        //Existing address cannot belong to a guest
        if (!$customerId) {
            throw new \Magento\Framework\Exception\NoSuchEntityException(
                __('Invalid customer address id %1', $address->getCustomerAddressId())
            );
        }
        //Validating address ID
        try {
            $this->addressRepository->getById($address->getCustomerAddressId());
        } catch (NoSuchEntityException $e) {
            throw new \Magento\Framework\Exception\NoSuchEntityException(
                __('Invalid address id %1', $address->getId())
            );
        }
        //Finding available customer's addresses
        $applicableAddressIds = array_map(function ($address) {
            /** @var \Magento\Customer\Api\Data\AddressInterface $address */
            return $address->getId();
        }, $this->customerRepository->getById($customerId)->getAddresses());
        if (!in_array($address->getCustomerAddressId(), $applicableAddressIds)) {
            throw new \Magento\Framework\Exception\NoSuchEntityException(
                __('Invalid customer address id %1', $address->getCustomerAddressId())
            );
        }
    }
}

/**
 * Validates the fields in a specified address data object.
 *
 * @param \Magento\Quote\Api\Data\AddressInterface $addressData The address data object.
 * @return bool
 * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer.
 * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid.
 */
public function validate(AddressInterface $addressData)
{
    $this->doValidate($addressData, $addressData->getCustomerId());

    return true;
}

/**
 * Validate address to be used for cart.
 *
 * @param CartInterface $cart
 * @param AddressInterface $address
 * @return void
 * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer.
 * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid.
 */
/*public function validateForCart(CartInterface $cart, AddressInterface $address): void
{
    $this->doValidate($address, $cart->getCustomerIsGuest() ? null : $cart->getCustomer()->getId());
}*/

public function validateForCart(CartInterface $cart, AddressInterface $address): void
{
    $this->doValidate($address, $cart->getCustomerId() ? $cart->getCustomer()->getId() : null );
}
}
1

Check this out: https://github.com/magento/magento2/issues/23618#issuecomment-929293382 (All credits to ssstankiewicz)

To fix inconsistency at checkout(after login etc. with customer_id and customer_is_guest = 1) can edit vendor/magento/module-quote/Model/Quote.php:857 (Magento 2.4.2) From:

if ($this->_customer) {
    $this->setCustomerId($this->_customer->getId());
}

To:

if ($this->_customer && $this->_customer->getId()) {
    $this->setCustomerId($this->_customer->getId());
    $this->setCustomerIsGuest(false);
}

Of course via patch or afterBeforeSave plugin:

public function afterBeforeSave(MagentoQuote $subject, MagentoQuote $result): MagentoQuote
{
    if ($result->getCustomerId()) {
        $result->setCustomerIsGuest(false);
    }

    return $result;
}
0

If you're getting this error when programmatically creating an quote/order, make sure to set the following if the quote/order should belong to a customer:

$quote->setCustomerIsGuest(false)

Your Answer

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

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