productVariantsBulkUpdate returning unexpected user error

I’m running this mutation

        mutation productVariantsBulkUpdate($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
            productVariantsBulkUpdate(allowPartialUpdates: true, productId: $productId, variants: $variants) {
              product {
                id
              }
              productVariants {
                id
                price
                compareAtPrice
              }
              userErrors {
                field
                message
              }
            }
          }

I’m updating the price and compare at price in the variant input only, but am somehow getting back this user Error:

    "user_errors": [
        {
            "field": [
                "variants",
                "0",
                "metafields",
                "0",
                "value"
            ],
            "message": "Value must be true or false."
        }
    ],

The mutation is not changing the price as expected, the existing price is returned in the response.

Example request ID: fc949945-172c-4580-9ad8-0a24a877c95d-1773736789
Shop ID: 95183438155

My request params are not specifying any metafield data, so that user error is very unexpected and seems to be a bug

I have never seen an error like this before when running that mutation from our app

If possible it would be very helpful if someone from Shopify could check the logs associated with that request ID and investigate why the server is responding with that user error

Hi @Chris_Geelhoed

Could you share your request parameters and the structural definition of the metafield?

I am specifying a valid product ID along with an array with one element with the id, price, and compareAtPrice specified

I don’t know the metafield details. My app is not specifying any metafield at all (part of my confusion) and the response from the Shopify server does not provide the details either.

I have spoken to the merchant and apparently they can’t even update the price of this variant using the admin dashboard UI, so it might be possible that the issue isn’t with the graphQL API so much as merchant data is somehow in a broken state

Hi @Chris_Geelhoed

We have given you the solutions below; use them, and it will work.

The value should be like this. A monetary value string without a currency symbol or code. Example value: "100.57".

mutation productVariantsBulkUpdate( $productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
productVariantsBulkUpdate(productId: $productId, variants: $variants) {
product {
id
}
productVariants {
id
price
compareAtPrice
}
userErrors {
field
message
code
}
}
}

pass Variables like

{
“productId”:“gid://shopify/Product/8208870047801”,
“variants”: [
{
“id”: “gid://shopify/ProductVariant/45600304562233”,
“price”: 99.99
},
{
“id”: “gid://shopify/ProductVariant/45600304595001”,
“price”: 49.99
}
]
}

Output:

{
“data”: {
“productVariantsBulkUpdate”: {
“product”: {
“id”: “gid://shopify/Product/8208870047801”
},
“productVariants”: [
{
“id”: “gid://shopify/ProductVariant/45600304562233”,
“price”: “99.99”,
“compareAtPrice”: “999.99”
},
{
“id”: “gid://shopify/ProductVariant/45600304595001”,
“price”: “49.99”,
“compareAtPrice”: “999.99”
}
],
“userErrors”: []
}
},
“extensions”: {
“cost”: {
“requestedQueryCost”: 10,
“actualQueryCost”: 10,
“throttleStatus”: {
“maximumAvailable”: 2000,
“currentlyAvailable”: 1990,
“restoreRate”: 100
}
}
}
}

Hey @Chris_Geelhoed , your instinct is right. I checked the logs for that request ID and can confirm your input only contained id, price, and compareAtPrice with no metafield data.

When productVariantsBulkUpdate saves the variant, Shopify validates all associated data including existing metafields. This variant has a boolean-type metafield with an invalid stored value (not “true” or “false”), and that validation failure blocks the entire save. Same reason the merchant can’t update the price in the admin UI.

To find the offending metafield, try querying the variant’s metafields and look for one with type of boolean:

query {
  productVariant(id: "gid://shopify/ProductVariant/53600143868235") {
    metafields(first: 20) {
      edges {
        node {
          id
          namespace
          key
          type
          value
        }
      }
    }
  }
}

If you can see it, fix the value with metafieldsSet or remove it with metafieldsDelete. If the metafield was created by another app with private namespace access, your app won’t be able to see it via the API. In that case, the merchant should check the variant’s metafields directly in the admin (the admin shows all metafields regardless of which app owns them) and correct or remove the invalid boolean value there. The merchant can also check Settings > Custom Data > Variants for any definitions flagged with invalid values.

Once that metafield is fixed, your price updates should work. Hope this helps!

1 Like

Thank you for the thoughtful reply @Donal-Shopify

The variant has several metafields visible to our app under the custom namespace but they all exist as single_line_text_field types.

Those must not be the issue, right? The problem must be a boolean field that somehow got saved without passing the current validation logic - right?

1 Like

Hi @Chris_Geelhoed

You are doing it wrong. You are writing in the post that there is a problem updating the price.

How can someone help you, if you were having problems with metafields and were told that there was a problem with Price? Then that is wrong, right?

Please explain the problem you are having next time so that the other person can solve your problem sincerely.

This made me feel like I was helping someone wrongly.

I appreciate you trying to help, but I think you might be slightly misunderstanding the issue at hand. The mutation to change the price cannot complete successfully because an existing metafield (that my app cannot see or access) is stuck in a broken state. The data for this particular variant for this particular store appears to be corrupted. It’s not really a matter of sending the right variables.

I’m going to mark the issue as solved since this isn’t specifically a GQL issue. Thanks everyone