Cannot remove bundled product using useApplyCartLinesChange in Checkout UI extension

Hey Guys!

We’re facing an issue with Checkout Extensions where a bundle product (using the Cart Transformation API) doesn’t get “removed” from the cart when using the useApplyCartLinesChange hook. We saw that this was reported in the community about a year ago - check https://community.shopify.com/t/cannot-remove-bundled-product-using-useapplycartlineschange-in-checkout-ui-extension/282328

Could anyone here help us understand if this has been addressed or if there’s a known workaround?

2 Likes

Hey Rafath!

Great to hear you’re exploring what’s possible with Functions and Checkout UI Extensions together :smiley:

I made a simple test where I used the default variant’s ID of the bundle parent, and it seems to work well for bundles made with both the merge and expand operations.

Sharing for reference!

import React from "react";
import {useEffect, useState, useRef} from "react";
import {
  reactExtension,
  useInstructions,
  useCartLines,
  useApplyCartLinesChange
} from "@shopify/ui-extensions-react/checkout";

// Set the entry points for the extension
const checkoutBlock = reactExtension("purchase.checkout.block.render", () => <BlockExtension />);
export { checkoutBlock };

 const removeVariantId = "gid://shopify/ProductVariant/HARDCODEIDFORTEST";
  const instructions = useInstructions();
  const cartLines = useCartLines();
  const applyCartLinesChange = useApplyCartLinesChange();

  const [isProcessing, setIsProcessing] = useState(false);

  useEffect(() => {
    const handleCartChanges = async () => {
      if (isProcessing) return;

      const removeVariantExists = cartLines.find(
        cartLine => cartLine.merchandise.id === removeVariantId
      );

      try {
        setIsProcessing(true);

        if (removeVariantExists && instructions.lines.canRemoveCartLine) {
          console.log('Starting removal process...');

          applyCartLinesChange({
            type: "removeCartLine",
            id: removeVariantExists.id,
            quantity: 1
          })
          .then(removeResult => {
            if (removeResult.type === 'error') {
              throw new Error(removeResult.message);
            }
            console.log('Successfully removed variant!');
          })
          .catch(error => {
            console.error('Error in cart operations:', error);
          })
          .finally(() => {
            console.log('Cart operations completed');
            setIsProcessing(false);
          });
        } else {
          console.log('No variants to remove');
          setIsProcessing(false);
        }

      } catch (error) {
        console.error('Error updating cart:', error);
        setIsProcessing(false);
      }
    };

    handleCartChanges();
  }, [cartLines, applyCartLinesChange, isProcessing]);

Hey Paige! Thanks for the response. Unfortunately, its still not working for us even though our code looks the same.

Here’s an example request id x-request-id: 066c6e04-cb20-41ef-bfec-0934eaedb53f-1760514060

GraphQL response: {
"data": {
"session": {
"negotiate": {
"__typename": "NegotiationResultPayload",
"result": {
"__typename": "NegotiationResultFailed",
"reportable": false
},
"errors": [
{
"code": "BASE_INTERNAL_ERROR",
"localizedMessage": "Internal error.", "nonLocalizedMessage": "Internal error.", "localizedMessageHtml": "Internal error.", "__typename": "GenericError"
}
]
},
"__typename": "Session"
}
}
}

import { useCartLineTarget, useApplyCartLinesChange } from "@shopify/ui-extensions-react/checkout";
const targetValue = useCartLineTarget();
const applyCartLinesChange = useApplyCartLinesChange();
const removeProductFromCart = async () => {
try {
let cartLineItemId = targetValue?.id;
const result = await applyCartLinesChange({
type: "removeCartLine",
id: cartLineItemId,
quantity: targetValue.quantity,
});
if (result.type === "error") {
console.error(result.message);
return;
}
} catch (error) {
consoleLog("error", error);
}
};

Hey @Paige-Shopify
I believe its only failing when there’s a “manual discount code” applied on checkout. We have tested this with Checkout Blocks app as well and can replicate the same behaviour there as well.

x-request-id 58d7b41e-2c63-4348-ac05-5d63269deba0-1760516924(for Checkout Blocks app)

Oh wow, I see what you mean!
My app is affected in the same way when a product discount is applied to the bundle.

Thank you for bringing this to our attention with a replication video and Request IDs.

I see the errors in our logs, but can’t quite put my finger on what could be causing this. Let me dig into this further to see what’s going on.

1 Like

Got this added to our backlog to fix, but at this time we aren’t able to provide a timeline for when it will be resolved.

We’ll provide an update on this post when it has :slight_smile:

In the meantime, I recommend returning some kind of feedback to the customer when they attempt to remove a bundle while a product discount is applied to it.