Magento 2's Phantom Deletions: Unsaved Quote Items and Product Visibility Woes

Magento 2's Phantom Deletions: Unsaved Quote Items and Product Visibility Woes

As e-commerce experts specializing in Magento migrations and platform optimization, we often monitor the pulse of the Magento community, especially critical bug reports that can impact store functionality. A recent GitHub issue (Issue #41424) has brought to light a significant bug within Magento 2’s quote totals collection process that can lead to unexpected and incorrect item removals from the shopping cart, particularly affecting newly added or unsaved items.

The Problem: Wrong Items Disappearing from Your Cart

Imagine a scenario where a customer reorders a past purchase, or adds multiple items to their cart simultaneously. If, during this process, one of the products becomes invisible in the catalog (e.g., disabled or out of stock), Magento 2's system for collecting quote totals can misidentify and remove the wrong item from the cart. Instead of flagging the unavailable product for deletion, a completely different, valid item might be removed, leaving the problematic item in the quote.

Reproducing the Glitch

The issue author, lbajsarowicz, provided a clear, minimal reproduction path on Magento 2.4-develop (PHP 8.3, vanilla installation). The core steps involve:

  • Creating two enabled simple products, A and B.
  • Adding both products to a new, unsaved quote.
  • Programmatically making product B (or its associated item) no longer visible in the catalog (e.g., $itemB->getProduct()->setStatus(Status::STATUS_DISABLED)).
  • Initializing addresses and calling $quote->collectTotals().

The expected outcome is that item B is marked as deleted, and item A remains. However, the actual result is the opposite: {"A": true, "B": false}, meaning item A is deleted, and B stays. A real-world example cited is reordering an item where a configurable product's variation has since been disabled.

The Technical Deep Dive: Why It Happens

The root cause lies deep within Magento's core quote logic, specifically in how items are identified and removed when they haven't yet been saved to the database. The method Magento\Quote\Model\Quote\Address\Total\Subtotal::_removeItem() attempts to remove an item by its ID: $address->getQuote()->removeItem($item->getId()).

For items that are newly added and not yet persisted, $item->getId() returns null. Consequently, Quote::removeItem() calls getItemById(null). The critical flaw is in Quote::getItemById() (app/code/Magento/Quote/Model/Quote.php:1514-1523), which compares $item->getId() == $itemId. When $itemId is null, this comparison returns true for the first item it encounters in the quote that also has a null ID. This leads to the incorrect item being targeted and flagged for deletion.

The issue author illustrated the problematic code path:

Magento\Quote\Model\Quote\Address\Total\Subtotal::_removeItem()
// app/code/Magento/Quote/Model/Quote/Address/Total/Subtotal.php:151-165
// ... calls ...
$address->getQuote()->removeItem($item->getId())
// ... which calls ...
Quote::getItemById()
// app/code/Magento/Quote/Model/Quote.php:1514-1523
// ... where comparison for null ID leads to wrong item selection ...

Consequences and Potential Fixes

Beyond the immediate incorrect item removal, this bug can lead to more severe issues. If the wrongly flagged item has no ID but still possesses options (like a configurable product child), saving the quote can result in foreign key errors, as previously reported in Issue #41415. This highlights a chain reaction of bugs stemming from this core logic flaw.

The issue report suggests two potential directions for a fix:

  • Modifying _removeItem() to directly remove the given item object when it has no ID, instead of relying on a lookup by ID.
  • Adjusting Quote::getItemById() to return false when a null ID is passed, preventing it from matching the first available unsaved item.

This bug, reported on Magento 2.4.x and marked "ready for confirmation," is currently in the standard Magento contributor workflow. While no official patch or community-contributed solution is yet available in the comments, the detailed analysis within the issue itself provides valuable insight for developers encountering similar phantom item removals.

For Magento merchants and developers, understanding such core system behaviors is crucial for maintaining a robust e-commerce platform. This issue underscores the complexity of quote management in Magento 2 and the importance of thorough testing, especially when dealing with dynamic product statuses and cart interactions.

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools