I have a checkout_cart_product_add_after event that calls to a observer file in which i want to check a condition. If that condition is false i block the product from adding to the cart and want to return a error message to the frontend.

I'm using this code if the condition is true:

            $this->_messageManager->addError(__('your custom message'));
            //set false if you not want to add product to cart
            $observer->getRequest()->setParam('product', false);
            return $this;

but if i do that i get a console error 500 with an error: jQuery.parseJSON requires a valid JSON string.

And the add button to cart button stays on adding...

How can i block the product from adding to the cart but the button also refreshes?

1 Answer 1


Try using a plugin.


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <type name="Magento\Checkout\Controller\Cart\Add">
        <plugin name="sr_product_add" type="SR\MagentoCommunity\Plugin\Checkout\Controller\Cart\Add" sortOrder="1"/>


namespace SR\MagentoCommunity\Plugin\Checkout\Controller\Cart;

use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Store\Model\StoreManagerInterface;

class Add
     * @var ManagerInterface
    private $messageManager;

     * @var Json
    private $json;

     * @var ProductRepositoryInterface
    private $productRepository;

     * @var StoreManagerInterface
    private $storeManager;

     * Add constructor.
     * @param ManagerInterface $messageManager
     * @param Json $json
     * @param ProductRepositoryInterface $productRepository
     * @param StoreManagerInterface $storeManager
    public function __construct(
        ManagerInterface $messageManager,
        Json $json,
        ProductRepositoryInterface $productRepository,
        StoreManagerInterface $storeManager
    ) {
        $this->messageManager = $messageManager;
        $this->json = $json;
        $this->productRepository = $productRepository;
        $this->storeManager = $storeManager;

    public function aroundExecute(
        \Magento\Checkout\Controller\Cart\Add $subject,
        \Closure $proceed
    ) {
        $productId = (int) $subject->getRequest()->getParam('product');
        if ($productId) {
            try {
                return $this->productRepository->getById($productId, false, $this->storeManager->getStore()->getId());
            } catch (\Exception $e) {

        if (false) {
            $this->messageManager->addErrorMessage('your custom message');
            $result = [];

            return $subject->getResponse()->representJson(

        return $proceed();
  • Thanks for replying, but how do i use this in my observer function?
    – Tom291
    Mar 7, 2019 at 8:00
  • You can't handle this by the observer, because all observers are fire after product add. So if you try by observer then you need to call delete again that product from cart. It easy to handle by plugin.
    – Sohel Rana
    Mar 7, 2019 at 8:25
  • Okay i understand how it works now. The problem is that i want to get the product object like in observer($observer->getEvent()->getProduct();). Any idea if i can also do that in the Add class?
    – Tom291
    Mar 7, 2019 at 8:32
  • Nevermind, i found out that you can retrieve the product id with $product_id = $this->request->getPostValue("product"); and after you can use $product = $objectManager->create('Magento\Catalog\Model\Product')->load($product_id); to retrieve the product object. Thanks!
    – Tom291
    Mar 7, 2019 at 11:27
  • Hey, don't use object manager. Try to use repository.
    – Sohel Rana
    Mar 7, 2019 at 11:56

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.