Detect if SelectedItem is part of a #tag

On my constant tirade of making a PvP map so far, I've successfully made or modified custom death message systems for arrows and falling to death with help from here, but I also want a system in which can detect melee deaths via swords and axes to create custom death messages there as well.

I figured that the same system I'm currently using for arrows could work similarly for swords, minor exception in that I'd need to create tags to verify if the attack was a sword or an axe.

Is there a way, however, to check if a player's SelectedItem is in a certain tag (eg. I put all the swords into one called #swords)? Or do I need to set up a function for each sword rather than just testing for swords in general?

In case it's needed, here's how the system works generally;

  1. Check for player death via something other than an arrow (drowning, burning from lava/fire, and fall damage are non-existent, and mobs are turned off, and the gamemode is Adventure which prevents block placement, therefore no other damage types can be made)
  2. Run "generic" kill check, looking for if it's a sword or an axe <-- This is where the search would be looked for
  3. Check for enchantments/tags on the sword/axe that's found

Yes, item tags exist. The item tag file would look like this:

swords.json

{
  "values": [
    "minecraft:wooden_sword",
    "minecraft:stone_sword",
    "minecraft:golden_sword",
    "minecraft:iron_sword",
    "minecraft:diamond_sword",
    "minecraft:netherite_sword"
  ]
}

Here it is, working:

Item tag

However, even though the wiki says that "Item tags can be called when testing for item arguments in commands with #(namespaced ID)", this does not seem to be true. This Reddit comment also confirms that this is not possible:

... [Testing for item tags] is not one of the functionalities of NBT item testing. You've got to remember that when testing for something's NBT, the entity has to have identical NBT to the one you're providing. No item will have the Item.id tag equal to "#bhtype:swords", unfortunately. Minecraft recognises it as a proper command because you have the Item.id value as an identifiable TAG_String, nothing more. ...

Here is a workaround:

execute unless entity @s[nbt=!{SelectedItem:{id:"minecraft:wooden_sword"}},nbt=!{SelectedItem:{id:"minecraft:stone_sword"}},nbt=!{SelectedItem:{id:"minecraft:golden_sword"}},nbt=!{SelectedItem:{id:"minecraft:iron_sword"}},nbt=!{SelectedItem:{id:"minecraft:diamond_sword"}},nbt=!{SelectedItem:{id:"minecraft:netherite_sword"}}] run say I'm holding a sword

Good luck on your PvP map :)


As ExpertCoder14 commented, "if you're using a data pack, you can use a predicate to test for an item tag."

This is what the predicate would look like:

holding_sword.json

{
  "condition": "minecraft:entity_properties",
  "entity": "this",
  "predicate": {
    "equipment": {
      "mainhand": {
        "tag": "test:swords"
      }
    }
  }
}

Then you could use this command:

/execute if predicate test:holding_sword run say I'm holding a sword