inventorySetOnHandQuantities provides strange results

I was looking for a way to update inventory in bulk, and tried inventorySetOnHandQuantities.

The update happens, but the returned results have 2 strange behaviours:

  • Each item is listed twice
  • The quantityAfterChange field always returns null

Is this expected? Or am I doing something wrong?

Thanks


QUERY

mutation inventorySetOnHandQuantities($input: InventorySetOnHandQuantitiesInput!) {
  inventorySetOnHandQuantities(input: $input) {
	userErrors { field message }
	inventoryAdjustmentGroup {        
        createdAt reason changes { name delta quantityAfterChange                 
} } }}

VARIABLES

{  "input": {    "reason": "correction",
	"setQuantities": [
	  {"inventoryItemId": "gid://shopify/InventoryItem/XXX",        
      "locationId": "gid://shopify/Location/XXX",        
      "quantity": 10      }
	]  }}

RESULT

{
    "data": {
        "inventorySetOnHandQuantities": {
            "userErrors": [],
            "inventoryAdjustmentGroup": {
                "createdAt": "2023-05-06T02:49:32Z",
                "reason": "correction",
                "changes": [
                    {
                        "name": "available",
                        "delta": -2,
                        "quantityAfterChange": null
                    },
                    {
                        "name": "on_hand",
                        "delta": -2,
                        "quantityAfterChange": null
                    }
                ]
            }
        }
    },
    "extensions": {
        "cost": {
            "requestedQueryCost": 11,
            "actualQueryCost": 11,
            "throttleStatus": {
                "maximumAvailable": 1000.0,
                "currentlyAvailable": 989,
                "restoreRate": 50.0
            }
        }
    }
}
1 Like

Hi @newbie_01 ,

Thanks for your post. The two listings coming back in the return result are for the different inventory states that were adjusted by the change (ā€˜available’ and ā€˜on_hand’), there’s a great reference about the inventory state labels here: [Shopify Docs: Inventory State Chart]

About quantityAfterChange returning null, that doesn’t seem like the expected result and we have been able to replicate so a report has been filed for further investigation.

Thanks and hope you have a great day,

Jon551

3 Likes

Hi @newbie_01 ,

The results of the investigation into quantityAfterChange returning null have found that this is expected behaviour when the request is initially submitted as it can take some time to process the inventory moves.

This is described in a bit more detail as comments in the example return values found [in the ā€˜Manage Inventory Quantities and States’ dev doc] like this:

This field always returns null immediately after running the mutation. The value of this field is available only after all written adjustments and moves have been processed.

We’re looking into getting this additional note added to the docs for [the inventorySetOnHandQuantities mutation] to make it more visible.

If you want to get the quantityAfterChange values later they can be queried on the InventoryAdjustmentGroup object like this, just remember to request the id for the inventoryAdjustmentGroup when performing inventorySetOnHandQuantities as it’s not in the example in the docs:

{
node(id: ā€œgid://shopify/InventoryAdjustmentGroup/1234567890ā€) {
…on InventoryAdjustmentGroup {
changes {
quantityAfterChange
}
}
}
}

Hope you have a great day,

Jon551

7 Likes

We’re using inventorySetOnHandQuantities in production for bulk inventory updates, and this mutation helped us remove a major bottleneck compared to single-item updates. However, while scaling this flow, we identified a few important edge cases worth sharing.

:one: ITEM_NOT_STOCKED_AT_LOCATION case
For items returning ITEM_NOT_STOCKED_AT_LOCATION, we trigger inventoryActivate / ActivateInventoryItem first.
However, activating the inventory item does not automatically trigger the quantity update in the same flow.
So the stock update needs to be retried after activation is fully processed, otherwise the quantity remains unchanged.

:two: Partial failure in bulk requests
Another critical point:
When sending bulk inventorySetOnHandQuantities, if one item fails, Shopify returns the mutation as failed for the whole request.
To avoid blocking large batches, our current approach is:

  • We detect failed items from the response

  • Retry only the failed inventory items, instead of re-sending the entire bulk payload

Bu yaklaşım özellikle high-volume stores için çok kritik. Aksi halde tek bir problemli item, binlerce stok güncellemesini kilitleyebiliyor.

Hope this helps anyone implementing bulk inventory sync at scale.