You can remove a product from the cart programmatically in WooCommerce by generating that product’s cart ID, locating its cart item key, and calling remove_cart_item() — useful for enforcing business rules automatically rather than asking customers to remove it manually.
Why Remove Cart Items Automatically
- Enforce rules like “this add-on can’t be purchased alone” by removing it if the main product is removed
- Automatically clear promotional items that are no longer eligible once cart contents change
- Remove out-of-stock or discontinued products that somehow remain in an old session
- Requires the cart item key, not just the product ID, which is the part that trips people up
Step 1: Find and Remove the Cart Item
/** Automatically remove a specific product from the cart on every page load */
add_action( 'template_redirect', 'strip_discontinued_product_from_cart' );
function strip_discontinued_product_from_cart() {
if ( is_admin() || ! WC()->cart ) {
return;
}
$target_product_id = 591;
$generated_cart_id = WC()->cart->generate_cart_id( $target_product_id );
$matching_item_key = WC()->cart->find_product_in_cart( $generated_cart_id );
if ( $matching_item_key ) {
WC()->cart->remove_cart_item( $matching_item_key );
}
}

Removing Based on a Condition, Not Always
/** Only remove the add-on product if the main product (ID 480) is no longer in the cart */
add_action( 'woocommerce_cart_updated', 'remove_orphaned_addon_product' );
function remove_orphaned_addon_product() {
$main_product_id = 480;
$addon_product_id = 591;
$main_in_cart = (bool) WC()->cart->find_product_in_cart( WC()->cart->generate_cart_id( $main_product_id ) );
if ( ! $main_in_cart ) {
$addon_item_key = WC()->cart->find_product_in_cart( WC()->cart->generate_cart_id( $addon_product_id ) );
if ( $addon_item_key ) {
WC()->cart->remove_cart_item( $addon_item_key );
}
}
}Troubleshooting
The product is removed but immediately gets re-added
Check whether another snippet or plugin auto-adds the same product on the same hook — running both at the same priority can create a conflict that looks like nothing happened.
find_product_in_cart() returns nothing even though the product is visibly in the cart
Products added with custom cart item data (like a personalization field) generate a different, unique cart ID each time — generate_cart_id() alone won’t match those without also passing the same variation/cart item data used originally.
Frequently Asked Questions
Does this trigger a cart notice telling the customer what happened?
Not by default — add a wc_add_notice() call right after the removal if you want to inform the customer why an item disappeared.
Can I remove all items matching a category instead of one product ID?
Yes, loop through WC()->cart->get_cart(), check each item’s product category, and call remove_cart_item() for any matches.
Is template_redirect the only hook I can use for this?
No, woocommerce_before_calculate_totals or woocommerce_cart_updated also work well depending on whether you need it to run on every page load or only when the cart changes.
Conclusion
Once you know that removing a product needs its cart item key, not just its product ID, you can remove a product from the cart programmatically for all kinds of business rules. Test conditional removals carefully with real cart combinations to avoid accidentally stripping items customers intentionally added.
See also How to Add a Product to the WooCommerce Cart Programmatically on Visit. Then read How to Remove Product Links on the Cart Page in WooCommerce.
Prefer no code? All-in-One Utilities Woo Add-on adds over 50 WooCommerce features, so you can switch them on without code.