Cart Transform API not working on version 2025-01

I was testing my Shopify App recently and noticed that the Cart Transform merge is no longer working on version 2025-01.

In the 2025-01 version of the API says that you use are supposed to use the term merge in the Shopify Function but the most up to date and stable version of the api (2025-07) it says you are supposed to use linesMerge.

Below I put a code block of the following:

  • My GraphQL input data
  • The contents of my run.js file
  • The output as Shown in my dev dashboard

If you take a look at my run.js code, you will see i am using the merge command at the end of the run function.

My code was working just a couple of weeks ago so I’m not sure what is going on. Please let me know how I can fix this.

//========== GraphQL Input Data for the Shopify Function

{
  "cart": {
    "lines": [
      {
        "id": "gid:\/\/shopify\/CartLine\/98a6b1a8-f7ec-401b-8287-b124c47c43fb",
        "quantity": 1,
        "bundleId": {
          "value": "5"
        }
      },
      {
        "id": "gid:\/\/shopify\/CartLine\/c6456931-21c8-4f66-8704-eed9314783fa",
        "quantity": 1,
        "bundleId": {
          "value": "5"
        }
      },
      {
        "id": "gid:\/\/shopify\/CartLine\/94714ab5-e458-4fe3-8d04-1c8ee44af690",
        "quantity": 1,
        "bundleId": {
          "value": "5"
        }
      },
      {
        "id": "gid:\/\/shopify\/CartLine\/b04dc235-3904-4643-8640-1a58ae37d680",
        "quantity": 1,
        "bundleId": {
          "value": "5"
        }
      }
    ]
  },
  "shop": {
    "metafield": {
      "value": "{\"parentVariantId\":\"gid:\/\/shopify\/ProductVariant\/51198624563487\",\"bundlesArray\":[{\"name\":\"Test Bundle\",\"id\":5,\"bundle_display_name\":\"\",\"bundle_checkout_title\":\"\",\"status\":\"active\",\"discount_type\":\"percentage\",\"static_discount_value\":\"20\",\"tiered_discounts\":\"[]\"}]}"
    }
  }
}


//========== Run.js file
export function run(input) {
  // Stores cart lines grouped by their bundle ID property
  const groupedItems = {};
  const metafieldData = JSON.parse(input.shop.metafield.value)

  const parentVariantId = metafieldData.parentVariantId
  const bundlesArray = metafieldData.bundlesArray
  const cartLines = input.cart.lines

  //console.log("VALUE OF Metafield Data post-parse", "Parent Gid: " + parentVariantId, "\n", "Bundles Array", bundlesArray)

  cartLines.forEach(line => {
    const bundleId = line.bundleId
    if(!bundleId?.value) return

    //create a new grouping for the bundle id if it doesn't have one yet
    if(!groupedItems[bundleId.value]){
      groupedItems[bundleId.value] = []
    }

    groupedItems[bundleId.value].push(line)
  })

  console.log(JSON.stringify(groupedItems))

  //Seems like this chunk of code is an array of arrays
  const cartOperations = Object.values(groupedItems).map(group => {
    const totalItemsInBundle = group.reduce((sum, line) => sum + line.quantity, 0);
    const bundleId = group[0].bundleId.value;

    const discountPercentage = calculatePercentageDiscount(bundlesArray, bundleId, totalItemsInBundle);
    const updatedBundleTitle = overrideBundleTitle(bundlesArray, bundleId);

    const lineItems = group.map(line => {
      return {
        cartLineId: line.id,
        quantity: line.quantity
      }
    })

    // console.log("Value of Line Items", JSON.stringify(lineItems))
    // console.log("Discount: " + discountPercentage)
    // console.log("Updated Title: " + updatedBundleTitle)

    return{
      merge: {
        cartLines: lineItems,
        //^ Variant ID of the Parent Product for the Bundler Cart Transform
        parentVariantId: parentVariantId,
        price: {
          percentageDecrease: {
            value: discountPercentage
          }
        },
        //Conditional object spread
        ...(updatedBundleTitle && { title: updatedBundleTitle })
      }
    }
  })

  return {
    operations: cartOperations
  }
};


function calculatePercentageDiscount(bundlesArray, bundleId, totalItemsInBundle) {
  const bundleConfig = bundlesArray.find(bundle => bundle.id == bundleId)

  if (!bundleConfig) {
    return 0;
  }
  if (bundleConfig.discount_type === "percentage") {
    return parseFloat(bundleConfig.static_discount_value) || 0;
  }
  if (bundleConfig.discount_type === "tiered_percentage") {
    const tieredDiscounts = JSON.parse(bundleConfig.tiered_discounts);
    const sortedTiers = tieredDiscounts.sort((a, b) => b.minItems - a.minItems);
    const applicableTier = sortedTiers.find(tier => totalItemsInBundle >= parseInt(tier.minItems));
    if (applicableTier) {
      return parseFloat(applicableTier.discount) || 0;
    }
  }
  return 0;
}

function overrideBundleTitle(bundlesArray, bundleId) {
  const bundleConfig = bundlesArray.find(bundle => bundle.id == bundleId);
  return bundleConfig?.bundle_checkout_title || null;
}

//========= Result of the Shopify Function:
{
  "operations": [
    {
      "linesMerge": {
        "cartLines": [
          {
            "cartLineId": "gid:\/\/shopify\/CartLine\/98a6b1a8-f7ec-401b-8287-b124c47c43fb",
            "quantity": 1
          },
          {
            "cartLineId": "gid:\/\/shopify\/CartLine\/c6456931-21c8-4f66-8704-eed9314783fa",
            "quantity": 1
          },
          {
            "cartLineId": "gid:\/\/shopify\/CartLine\/94714ab5-e458-4fe3-8d04-1c8ee44af690",
            "quantity": 1
          },
          {
            "cartLineId": "gid:\/\/shopify\/CartLine\/b04dc235-3904-4643-8640-1a58ae37d680",
            "quantity": 1
          }
        ],
        "parentVariantId": "gid:\/\/shopify\/ProductVariant\/51198624563487",
        "price": {
          "percentageDecrease": {
            "value": 20
          }
        }
      }
    }
  ]
}

And this what the result looks like in checkout:

Hey @Patrick_Pierre

If you use linesMerge on 2025-01 does this work? It’s possible there was a change to this version which may not have been documented.

@Liam-Shopify Thanks for your response.

I tried using linesMerge and I got the following error message:

[{"path":["operations",0],"explanation":"Expected one of valid values: expand, merge, update, lineAdd. Got: linesMerge"}]

I also tried updating the API version to 2025-07 in shopify.extension.toml file and using linesMerge still failed. And when I use merge, the logs don’t show any errors but the bundling is still unsuccessful.

Based on the code I posted, do you think I am making any other mistakes that might be causing this?

Hi again @Patrick_Pierre

From what I’m seeing you should use merge for 2025-01 and earlier and linesMerge for 2025-07 and later. Since this is not working as expected there could be other things to look out for like making sure your function export matches the target (e.g., cartTransformRun for 2025-07).

Also always regenerate types and check your input/output against the latest schema, and if you’re using the Shopify CLI, make sure to run shopify app function typegen after changing the API version.

If you’re still seeing no effect in the checkout after using the correct key, double-check that your function is being deployed and invoked, and that your input data matches the expected structure.

Hey Liam,

Thank you for your help. I have tried everything you mentioned but I am still unable to get the function to apply the product merging logic in the checkout, despite all execution logs showing success.

I have performed a detailed review and can confirm that all configuration and function logic appears correct according to the latest documentation.

The function is successfully invoked, processes the input, and returns the expected output . However, once I got to checkout I can see that the Cart Lines are not merged even though the function shows it has run successfully in my logs.

Here is an example of a “successful” run:

{
  "operations": [
    {
      "linesMerge": {
        "cartLines": [
          {
            "cartLineId": "gid:\/\/shopify\/CartLine\/c58692a1-f773-4a44-abc0-61d187d3c74a",
            "quantity": 1
          },
          {
            "cartLineId": "gid:\/\/shopify\/CartLine\/ec11b7f8-13f3-44a8-b433-2294c57e4241",
            "quantity": 1
          }
        ],
        "parentVariantId": "gid:\/\/shopify\/ProductVariant\/51274048569631",
        "price": {
          "percentageDecrease": {
            "value": 20
          }
        }
      }
    }
  ]
}

Confirmed Troubleshooting and Setup Verification

To rule out common issues, I have verified the following points:

  1. Function and Version: I deleted the previous function and created a new one using the , setting the version to .

  2. Activation and Deployment: The new function was activated using the mutation and successfully deployed to the Partner Dashboard.

  3. Function Export: The function’s export matches the required target: for the version.

  4. Type Generation: I have consistently regenerated types using after any changes to the version or input query, confirming the input/output structures match the latest schema.

  5. Environment: The development store is utilizing (not ).

  6. Transform Uniqueness: I have verified that my app’s is the only one currently active on the development store.

  7. Input Data: I have confirmed that the for the required parent product variant is correct within the function logic.

  8. Execution Logs: The function is being invoked successfully, and all runs complete with no errors or failed statuses visible in the Partner Dashboard logs.

  9. Output Structure: The output for the operation has been structurally verified and matches the expected format per the documentation.

Request for Guidance

I feel like I tried everything so I’m not sure what to do next. This is the last thing stopping me from submitting my app and I’ve been dealing with this issue for weels.

Any help you can provide to me would be much appreciated.

I managed to fix this issue and wanted to add this update for anyone that might experience the same problem I was dealing with.

The issue wasn’t the Cart Transform itself, but how the parent product was created. I used a GraphQL mutation and set the product to active, and it looked fine on the store preview, so I thought I was good.

But it turns out the product wasn’t properly registered with the Online Store sales channel. Once I manually added it to that channel, the Cart Transform immediately started working.

I need to go tweak my mutation to make sure the product gets added to the online store sales channel when my app sends the mutation to create the parent product.

Hope this helps anyone else running into the same odd behavior!