Solved

Bulk updating variant metafields with productVariantsBulkUpdate failing (version 2022-04 and 07)

EricCholis
Tourist
3 0 3

I'm using productVariantsBulkUpdate graphql mutation to update variant pricing and metafields. But, the metafields update is failing. If I pass id and value for the metafield definition, I receive errors stating I need to include key, namespace, etc.. (X can't be blank or X is too short).

 

If I include everything (id, namespace, key, name, type), I receive a "

Key must be unique within this namespace on this resource" error.

 

My first inclination is that the input is somehow assuming that I'm attempting to create a new metafield, even if an id is passed.

 

My sample mutation:

 

 

mutation productVariantsBulkUpdate($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
  productVariantsBulkUpdate(productId: $productId, variants: $variants) {
    product {
      id
    }
    productVariants {
      id,
      sku
      price
      metafields(first: 10) {
        edges {
          node {
            id
            namespace
            key
            value
          }
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}

 

 

Sample input (actual ids removed):

 

{
    "productId": "gid://shopify/Product/<id>",
    "variants": [
        {
            "id": "gid://shopify/ProductVariant/<variant_id>",
            "price": "275",
            "metafields": [
                {
                    "id": "gid://shopify/Metafield/<field_1>",
                    "value": "266.75"
                },
                {
                    "id": "gid://shopify/Metafield/<field_2>",
                    "value": "265.29"
                },
                {
                    "id": "gid://shopify/Metafield/<field_3>",
                    "value": "263.92"
                },
                {
                    "id": "gid://shopify/Metafield/<field_4>",
                    "value": "262.4"
                },
                {
                    "id": "gid://shopify/Metafield/<field_5>",
                    "value": "261.14"
                }
            ]
        },
        {
            "id": "gid://shopify/ProductVariant/<variant_id>",
            "price": "15",
            "metafields": [
                {
                    "id": "gid://shopify/Metafield/<field_1>",
                    "value": "14.55"
                },
                {
                    "id": "gid://shopify/Metafield/<field_2>",
                    "value": "14.47"
                },
                {
                    "id": "gid://shopify/Metafield/<field_3>",
                    "value": "14.4"
                },
                {
                    "id": "gid://shopify/Metafield/<field_4>",
                    "value": "14.31"
                },
                {
                    "id": "gid://shopify/Metafield/<field_5>",
                    "value": "14.24"
                }
            ]
        }
    ]
}

 

If I remove the metafields altogether, the price bulk updates work fine. 

 

Accepted Solution (1)

Bradley-Staff
Shopify Staff
3 3 4

This is an accepted solution.

Hi @EricCholis

I  used the code you posted above, simplified the input down to one product variant with two metafields, and remove namespace and key from the sample mutation, and it worked with API Version 2022-04, so I don't think there's anything wrong with the actual structure of your mutation or input.

One way in which the API can return the errors you mentioned ("Type can't be blank", "Namespace can't be blank", etc) , even when you provide a metafield.idis if the metafield.id provided does not match any metafield that exists for that product variant. I verified this myself (albeit accidentally) when I pasted the wrong ID into my own mutation's query variables / input.

Please note that this must ID be a metafield ID (not a metafield definition ID) and it must an ID of a metafield belonging to the product variant specified.

If you'd like to verify the IDs of the metafields on a given product variant, you can use the following query, modified to fit your needs.

query getProductVariantMetafieldIDs {
  productVariant(id: "gid://shopify/ProductVariant/<Product_Variant_ID>") {
    title
    metafields(first: 10) {
      edges {
        node {
          id
          namespace
          key
          value
        }
      }
    }
  }
}

 
Hopefully this will help solve your issue, let me know!

To learn more visit the Shopify Help Center or the Community Blog.

View solution in original post

Replies 7 (7)

Bradley-Staff
Shopify Staff
3 3 4

This is an accepted solution.

Hi @EricCholis

I  used the code you posted above, simplified the input down to one product variant with two metafields, and remove namespace and key from the sample mutation, and it worked with API Version 2022-04, so I don't think there's anything wrong with the actual structure of your mutation or input.

One way in which the API can return the errors you mentioned ("Type can't be blank", "Namespace can't be blank", etc) , even when you provide a metafield.idis if the metafield.id provided does not match any metafield that exists for that product variant. I verified this myself (albeit accidentally) when I pasted the wrong ID into my own mutation's query variables / input.

Please note that this must ID be a metafield ID (not a metafield definition ID) and it must an ID of a metafield belonging to the product variant specified.

If you'd like to verify the IDs of the metafields on a given product variant, you can use the following query, modified to fit your needs.

query getProductVariantMetafieldIDs {
  productVariant(id: "gid://shopify/ProductVariant/<Product_Variant_ID>") {
    title
    metafields(first: 10) {
      edges {
        node {
          id
          namespace
          key
          value
        }
      }
    }
  }
}

 
Hopefully this will help solve your issue, let me know!

To learn more visit the Shopify Help Center or the Community Blog.

ozzyonfire
Shopify Partner
47 2 17

I think you are on the right track. I remember something similar happening to me when I was attempting the same thing.

 

If it your first time running the script, then it will run no problem - it creates the metafields.

When you go to update the same metafields, it returns an error and doesn't work. 

 

I think there is an updateMetafield operation where you can just supply the id and the value. It worked when I tried it this way.

 

I ended up switching strategies and used the Bulk Operation endpoint in order to update a bunch of metafields in bulk.

 

So the mutation looks like:

mutation {
  bulkOperationRunMutation(
    mutation: "mutation call($input: ProductVariantInput!) {
      productVariantUpdate(input: $input) {
        productVariant {
          sku
          id
        }
        userErrors {
          message
          field
        }
      }
    }", 
    stagedUploadPath: "https://shopify.s3.amazonaws.com/tmp/23217864751/bulk/f18d82c0-bde6-4073-a424-d3b4090c4325/5dc446ca7e6b3b001e61251b-price-update.jsonl") 
  {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}

 

And a sample .jsonl file would look like

{"input":{"id":"gid://shopify/ProductVariant/35615560433822","metafields":[{"id":"gid://shopify/Metafield/22817953448154","namespace":"easy-sync","key":"expected-delivery","type":"date","value":"2022-02-24"}]}}
{"input":{"id":"gid://shopify/ProductVariant/30304064667695","metafields":[{"namespace":"easy-sync","type":"string","key":"retail-price","value":"4.08"}]}}
{"input":{"id":"gid://shopify/ProductVariant/35615560368286","metafields":[{"id":"gid://shopify/Metafield/22817953611994","namespace":"easy-sync","key":"expected-delivery","type":"date","value":"2022-02-24"}]}}
{"input":{"id":"gid://shopify/ProductVariant/35615560695966","metafields":[{"id":"gid://shopify/Metafield/22817953775834","namespace":"easy-sync","key":"expected-delivery","type":"date","value":"2022-02-24"}]}}
{"input":{"id":"gid://shopify/ProductVariant/35615560663198","metafields":[{"id":"gid://shopify/Metafield/22817953644762","namespace":"easy-sync","key":"expected-delivery","type":"date","value":"2022-02-24"}]}}
{"input":{"id":"gid://shopify/ProductVariant/35615560827038","metafields":[{"id":"gid://shopify/Metafield/22817953677530","namespace":"easy-sync","key":"expected-delivery","type":"date","value":"2022-02-24"}]}}
{"input":{"id":"gid://shopify/ProductVariant/30305404911663","metafields":[{"namespace":"easy-sync","type":"string","key":"retail-price","value":"3.40"}]}}

 

May be worth a try if you are still having issues.

EricCholis
Tourist
3 0 3

Looks like I misunderstood that the Metafield ID is unique to each product or variation (in this context). I thought the ID that in the request should be the MetafieldDefinition value. Also, even though you can see all the Metafields on a variation in the Admin; it won't be in the return from productVariant if it's blank.

 

Appreciate the guidance  @ozzyonfire and @Bradley-Staff.

SilasGrygier
Shopify Partner
19 2 7

Can you recommend a way to bulk insert/update metafields for products? not productVariants, thanks in advance! 🙂

EricCholis
Tourist
3 0 3

The only thing that comes to mind immediately is to issue multiple productUpdate mutations in a single GraphQL call. You'd need to keep an eye on the query cost and your remaining points.

SilasGrygier
Shopify Partner
19 2 7

Thanks for the response Eric! It's possible to do a product update but I figured it's quite complicated because you would need to declare whether you are updating or inserting a new metafield for every product that you insert while also defining the metafield id for every product which is an extra headache, I figured that it's possible to update/create metafields using the metafieldsset bulk operation which takes in the same format for update & insert operations and it also doesn't require the metafield id, only the product id it's related to which is great! 🙂 

stats_marketing
Shopify Partner
25 3 11

@SilasGrygier 


@SilasGrygier wrote:

Thanks for the response Eric! It's possible to do a product update but I figured it's quite complicated because you would need to declare whether you are updating or inserting a new metafield for every product that you insert while also defining the metafield id for every product which is an extra headache, I figured that it's possible to update/create metafields using the metafieldsset bulk operation which takes in the same format for update & insert operations and it also doesn't require the metafield id, only the product id it's related to which is great! 🙂 


For some reason I keep getting errors with the JSONL file structure for this Operation.

error: 

Unexpected file structure - expected JSONL

 

Do you have a JSONL file format that worked as I have tried various aspects of the below JSONL format all with the same error mentioned above:

 

{"metafields":{"key": "my_key", "value": "This is a value", "namespace": "my_namespace", "ownerId": "gid://shopify/Product/6691584180295", "type": "single_line_text_field" }}

 

**UPDATE**

So it was valid JSONL the whole time.  The problem was the `POST` `file` structure.

 

Utilizing PHP 8 I had to change this:

$json['file'] = 'mydata.jsonl';

to this

$json['file'] = new CURLFile('mydata.jsonl');