Balena device tag PATCH updates all tags

Hi, I think I found a bug with the Balena Device Tag API. If we update a tag using the PATCH HTTP method, it looks like all the tags on that device get set to the new value, instead of only updating the tag with the specified key.

Here’s a quick script that triggers the issue:

API_TOKEN=<YOUR_TOKEN>
DEVICE_ID=<YOUR_DEVICE_ID>
curl -X POST "https://api.balena-cloud.com/v4/device_tag" -H "Content-Type: application/json" -H "Authorization: Bearer ${API_TOKEN}" --data '{ "device": '${DEVICE_ID}', "tag_key": "tag1", "value": "value1" }'
curl -X POST "https://api.balena-cloud.com/v4/device_tag" -H "Content-Type: application/json" -H "Authorization: Bearer ${API_TOKEN}" --data '{ "device": '${DEVICE_ID}', "tag_key": "tag2", "value": "value2" }'
curl -X POST "https://api.balena-cloud.com/v4/device_tag" -H "Content-Type: application/json" -H "Authorization: Bearer ${API_TOKEN}" --data '{ "device": '${DEVICE_ID}', "tag_key": "tag3", "value": "value3" }'
curl -X PATCH "https://api.balena-cloud.com/v4/device_tag" -H "Content-Type: application/json" -H "Authorization: Bearer ${API_TOKEN}" --data '{ "device": '${DEVICE_ID}', "tag_key": "tag3", "value": "new_value3" }'

Hi @nicktardif, thanks for the report. I reproduced it on my side and I’m chasing up the bug with our API engineers. I will follow up here once I know now.

Hi @nicktardif,
It seems that the PATCH cURL that you provided isn’t doing an OData filter and that’s why all device tags were affected.
Here is a PATCH cURL that updates the tag value of a tag with a specific key and of a specific device

API_TOKEN=<YOUR_TOKEN>
DEVICE_ID=<YOUR_TARGET_DEVICE_ID>
TAG_KEY=<YOUR_TARGET_TAG_KEY>
curl "https://api.balena-cloud.com/v5/device_tag?\$filter=(device%20eq%20$DEVICE_ID)%20and%20(tag_key%20eq%20%27$TAG_KEY%27)" -X PATCH -H "Authorization: Bearer ${API_TOKEN}" -H 'content-type: application/json' --data-binary '{"value":"new_value3"}'

Cool that worked, thank you @shaunmulligan and @thgreasi !

Here is a solution that works with the current version V6

curl -X PATCH \
"https://api.balena-cloud.com/v6/device_tag?\$filter=device/uuid%20eq%20'<UUID>'%20and%20tag_key%20eq%20'<TAG_KEY>'" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTH_TOKEN>" \
--data '{
    "value": "<NEW-VALUE>"
}'