A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
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.
Solved! Go to the solution
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.
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.
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.
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.
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.
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.
Can you recommend a way to bulk insert/update metafields for products? not productVariants, thanks in advance! 🙂
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.
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! 🙂
@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');