The id
and lvl
tags for enchantments are intended to have the "short" datatype. However, item data generally does not auto-correct itself like it would with entity data.
For example, if you summon the following entity, the Invulnerable
tag was incorrectly declared as an integer even though it's meant to be a byte:
/summon Creeperminecraft:creeper ~ ~1 ~ {Invulnerable:1}
The game will read the numerical value leniently, allowing you to declare the wrong datatype and it will still work. However, the game will appropriately save the tag's value as a byte, which is why you need to declare the correct datatype when testing for that data (which requires you to declare all data as it's saved and has no leniency in numerical datatypes):
/testforexecute @e[type=Creeper]if entity @e[type=Creeper,nbt={Invulnerable:1b}]
But most item data will save the same way it was read. Since you declared the id
and lvl
tags as integers, they will remain as integers. But under normal circumstances, such as enchanting, these tags are created as shorts.
You will want to create them with the expected datatype. To declare a short, you append the numerical value with an "s"s
like so:
/give @p minecraft:diamond_sword 1 0 {enchEnchantments:[{id:2s"minecraft:sharpness",lvl:4s}]} 1
And your /testforblockexecute if block
command will declare them as a short as well, which allows you to detect the provided item as well as items enchanted normally:
/testforblockexecute if block ~1 ~ ~ minecraft:chest -1 {Items:[{id:"minecraft:diamond_sword",tag:{enchEnchantments:[{id:2s"minecraft:sharpness",lvl:4s}]}}]}