GraphQL set inventory if product is not tracking stock

Good morning,

I noticed that the GraphQL inventorySetQuantities mutation does not return an error if setting the quantity on an inventory item which is not tracking its stock (there’s no error but still the quantity is not updated).
However, doing the same with the REST endpoint inventory_levels/set.json returns an 422 Unprocessable Content error saying that Inventory item does not have inventory tracking enabled.
Is this by design so? Is there a way to trigger the error with the GraphQL mutation?

Thank you!
Piotr

1 Like

Hey @Piotr_Wojcicki :waving_hand: - thanks for mentioning this here - I was able to replicate the behaviour in GraphQL that you’re seeing on my end here as well, that is odd. I’ll do some more digging into this to see if this is expected or something we can triage as an issue/feature request and loop back with you when I have some more info to share.

Hey again @Piotr_Wojcicki - just following up here. We’re digging into this further and treating it as a possible issue on our end. Can’t guarantee turnaround time, but I’ll post here when I have confirmation in terms of it being a possible bug/next steps - thanks again for reporting this :slight_smile:

Hey @Piotr_Wojcicki :waving_hand: - just following up again with you here. I was able to investigate this further on my end and can confirm that this is currently expected behaviour.

That said, we do definitely recognize that it’s not the most intuitive and we can for sure improve the performance of the mutations.

I’ve set a feature request report so that we can track this as a possible future enhancement to work further on. I can’t guarantee anything specifically, but in the past I’ve seen feature requests I’ve created get implemented in releases, so that does happen in many cases.

Hope this helps - let me know if I can clarify anything on my end here, happy to help out further!

So, to confirm, for some reason using RESTful it is an error situation, but in GraphQL it is not, and this is intentional? Put another way, it doesn’t hurt anything to use the GraphQL method of setting the inventory level.

In my case, I have a similar situation, just wanted to confirm if I need to worry about it or not.

BTW, here is my python code (using library shopify_python_api), where, in my case, I use inventorySetOnHandQuantities:

                           mutation = """
                            mutation inventorySetOnHandQuantities($input: InventorySetOnHandQuantitiesInput!) {
                              inventorySetOnHandQuantities(input: $input) {
                                userErrors {
                                  field
                                  message
                                }
                              }
                            }
                            """
                            variables = {
                                "input": {
                                    "setQuantities": [
                                        {
                                            "inventoryItemId": inventory_item_id,
                                            "locationId": f"gid://shopify/Location/{location_id}",
                                            "quantity": new_qty
                                        }
                                    ],
                                    "reason": "correction"
                                }
                            }
                            mutation_result = shopify.GraphQL().execute(mutation, variables=variables)

Hey @Anthony_Baldarelli :waving_hand:

Thanks for following up here.

Just confirming that for GraphQL, this is indeed expected behavior.

With GraphQL, the inventorySet mutations are currently set up to accept requests for non-tracked inventory items and return success without actually updating quantities, while REST returns that explicit 422 error.

I can’t say for sure why this difference exists, but my understanding (without revealing too much internal info) is that GraphQL is a bit more permissive to avoid failing entire bulk operations in cases where certain inventory items can’t be updated but others can (more info here).

That said, the inconsistency isn’t ideal for developers for sure, and while I can’t promise specific timelines, I did just want to confirm we’re for sure tracking this for potential improvement.

In the meantime, if you need to handle these cases explicitly, my recommendation would be to either check the tracked field before attempting updates, or verifying the quantity was actually updated by querying it in the mutation response (or as a separate query after the mutation).

Taking a look there though, I don’t think your current code would cause any harm, it just won’t update quantities for non-tracked items as you mentioned. Hope this helps clarify things a bit, let me know if I can help out further as always :slight_smile:

Thanks. This is crazy, but I think it actually does update it. Just cannot see the new value the store UI (it is empty and greyed out). I believe this because I have code to NOT update if nothing has changed (I do a query first), and if I run the same update twice, the second update won’t happen, as it won’t even be attempted, because there was no change.

Also, as a further test, I changed my mutation to give back more information:

                           mutation = """
                            mutation inventorySetOnHandQuantities($input: InventorySetOnHandQuantitiesInput!) {
                              inventorySetOnHandQuantities(input: $input) {
                                userErrors {
                                  field
                                  message
                                }
                                inventoryAdjustmentGroup {
                                  changes {
                                    delta
                                    quantityAfterChange
                                    item {
                                      id
                                      sku
                                      tracked
                                      variant {
                                        inventoryQuantity
                                      }
                                    }
                                  }
                                }
                              }
                            }
                            """
                            variables = {
                                "input": {
                                    "setQuantities": [
                                        {
                                            "inventoryItemId": inventory_item_id,
                                            "locationId": f"gid://shopify/Location/{location_id}",
                                            "quantity": new_qty
                                        }
                                    ],
                                    "reason": "correction"
                                }
                            }
                            mutation_result = shopify.GraphQL().execute(mutation, variables=variables)

and I got this:

Changing available quantity from 50 to 5, item id gid://shopify/InventoryItem/<SKUID>, sku <SKU>, tracked False
=== Parsed mutation_data ===
{
  "data": {
    "inventorySetOnHandQuantities": {
      "userErrors": [],
      "inventoryAdjustmentGroup": {
        "changes": [
          {
            "delta": -45,
            "quantityAfterChange": null,
            "item": {
              "id": "gid://shopify/InventoryItem/<SKUID>",
              "sku": "<SKU>",
              "tracked": false,
              "variant": {
                "inventoryQuantity": 5
              }
            }
          },
          {
            "delta": -45,
            "quantityAfterChange": null,
            "item": {
              "id": "gid://shopify/InventoryItem/<SKUID>",
              "sku": "<SKU>",
              "tracked": false,
              "variant": {
                "inventoryQuantity": 5
              }
            }
          }
        ]
      }
    }
  },
  "extensions": {
   // No idea what this is, so snipped it
    }
  }
}
=== End mutation_data ===

So that is weird. Yes, this is the update I expected to happen (from 50 down to 5). Since I see nothing in UI, I would never have noticed it without either querying before I did the update, or checking the response after the update. For tracked items, I can see the change in the UI via “Adjustment History”, but no such option for non-tracked items.

So long as the store is not harmed, maybe it is OK. Just quite weird.

Is this one of those rare cases where the RESTful route is actually safer?