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.
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.
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.