How do I detect a player holding an item with nbt data?

I am making a Minecraft map and I want a door (made of blocks) to disappear when a player presses a button with the key in their hand. However, the player will be able to access multiple keys at once, so I need to detect exactly which key the player is holding. Using a basic online /give generator, I have made the keys have custom names and lore, but now I need my execute command to detect the NBT data this creates.

Doing some research, I didn't find much. Most of the things I find, from here or otherwise, are about previous versions of Minecraft, while I am using the latest version, 1.16.3.

I have a command currently that should work, but doesn't. When I hold the key in my hand and activate the command block, nothing happens. No error message in the command block's output, it just doesn't work.

Here's the command I am currently using:

execute if entity @p[nbt={SelectedItem:[{id:"minecraft:tripwire_hook", tag:{display:{Name: '[{"text":"Lockroom Key","italic":false}]', Lore: ['[{"text":"The key to the Lockroom door.","italic":false,"color":"dark_gray"}]']}}}]}] run fill 233 36 47 234 34 49 minecraft:air replace

This command is accepted as valid in a command block, it just doesn't do anything. The key I am holding has the same NBT data as specified.


Solution 1:

You are so close, but your SelectedItem tag is wrong. The SelectedItem tag is a compound tag directly, not an array tag.

Wrong way:

{SelectedItem:[{id:"minecraft:dirt"}]}

Right way:

{SelectedItem:{id:"minecraft:dirt"}}

So to fix your problem, remove these two square brackets:

execute if entity @p[
    nbt={
        SelectedItem:[ <--[HERE]
            {
                 id:"minecraft:tripwire_hook",
                 tag:{
                     display:{
                         Name: '[{"text":"Lockroom Key","italic":false}]',
                         Lore: [
                            '[{"text":"The key to the Lockroom door.","italic":false,"color":"dark_gray"}]'
                         ]
                     }
                 }
             }
        ] <--[HERE]
    }
]

To make this:

execute if entity @p[nbt={SelectedItem:{id:"minecraft:tripwire_hook", tag:{display:{Name: '[{"text":"Lockroom Key","italic":false}]', Lore: ['[{"text":"The key to the Lockroom door.","italic":false,"color":"dark_gray"}]']}}}}] run fill 233 36 47 234 34 49 minecraft:air replace

The best resource to find all the info you need is the Minecraft Wiki. The page I just linked is the structure of NBT on a player’s file, including the item structure. If you look at the SelectedItem tag, you can see that is a compound tag.