Minecraft – Testforblock finds an item I have summoned, but not one I made

minecraft-commandsminecraft-java-edition

I'm using the following command in a command block to test for an enchanted diamond sword in a chest next to the command block:

/testforblock ~1 ~ ~ minecraft:chest -1 {Items:[{id:minecraft:diamond_sword,tag:{ench:[{id:2,lvl:4}]}}]}

It detects a sword that I used /give to get that already had Feather Falling 4, but it doesn't detect a Feather Falling sword that I made using the anvil. Neither are named and are identical otherwise.

Is there some tag that differentiates the two? How would I get my command block to accept both?

(Feather Falling was just one I picked while I get the command down)

Best Answer

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 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):

/testfor @e[type=Creeper] {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":

/give @p minecraft:diamond_sword 1 0 {ench:[{id:2s,lvl:4s}]}

And your /testforblock command will declare them as a short as well, which allows you to detect the provided item as well as items enchanted normally:

/testforblock ~1 ~ ~ minecraft:chest -1 {Items:[{id:"minecraft:diamond_sword",tag:{ench:[{id:2s,lvl:4s}]}}]}