Wiki 9Minecraft Wiki 9Minecraft

Item Drop Detection Command Recipe

Detect dropped item entities on the ground or track when a player throws an item out of their inventory.

6Sections
5Code examples
3Known errors

Item drop detection lets a Behavior Pack react when an item entity appears in the world or leaves a player's inventory. You reach for this pattern when building floor-crafting altars, throwable ability tokens, custom trash bins, or puzzles where players sacrifice items on a pressure plate. In modern Bedrock Edition, you can solve this purely with target selectors, with the Hasitem filter for inventory loss, or by combining target selectors with an animation controller on the player.

How Bedrock Represents Dropped Items

When an item is dropped, mined from a block, or spat out by a dispenser, Minecraft Bedrock creates an entity with the identifier `minecraft:item`. Unlike Java Edition, Bedrock does not expose raw NBT compounds like `{Item:{id:"minecraft:diamond"}}` inside command target selectors. You cannot read the item's identifier, aux value, or stack count directly through a standard `@e[type=item]` selector argument.

Instead, Bedrock commands identify dropped items through their display name using the `name=` selector argument, or indirectly by polling the player's inventory before and after the drop using the `hasitem` selector filter. Understanding this limitation is the core of choosing the right detection recipe for your add-on. If you only need to know that an item is on the ground in a specific spot, `@e[type=item]` combined with `name=` is enough. If you need to know who dropped it, or if the item has been renamed at an anvil, you must track the player's inventory state or use the Script API.

Detection MethodIdentifies Item TypeSurvives Anvil RenameTracks Dropping Player
@e[type=item,name="..."]By localized display name onlyNo (matches the new custom name)Approximate (nearest player via @p)
Player hasitem quantity=0By exact item ID and dataYesExact (runs on the player)
Entity Spawn Event (Script API)By full ItemStack propertiesYesApproximate (velocity/proximity check)

Basic Ground Detection with Target Selectors

The fastest way to detect a specific dropped item is to target `type=item` and filter by the `name` argument. In Bedrock Edition, the `name` selector on an item entity checks the translated display name of the item in the server's active language (usually `en_US` for dedicated servers, or the host's language in singleplayer). If a player drops a diamond, the entity matches `@e[type=item,name="Diamond"]`.

To build a reliable floor-crafting or altar trigger, run a `.mcfunction` file every tick via `tick.json`. The function should execute at the dropped item, verify whether it is sitting on the correct block or near a secondary ingredient, trigger the reward, and then immediately `kill` the item entity so the command does not fire a second time on the next tick.

Be careful with multi-word item names and capitalization. While the `name` filter is generally case-insensitive in selector parsing, spaces require wrapping the string in quotation marks. Always test the exact display name in-game, because some legacy items have internal display names that differ slightly from their item IDs (for example, `minecraft:dye` vs `Lapis Lazuli`, or `minecraft:redstone` vs `Redstone Dust`).

BP/functions/altar/check_sacrifice.mcfunction
# Tag any Emerald item sitting directly on top of a Gold Block
execute as @e[type=item,name="Emerald",tag=!processed] at @s if block ~ ~-1 ~ minecraft:gold_block run tag @s add sacrifice_valid

# Grant effect and sound to the nearest player within 5 blocks of the valid item
execute at @e[type=item,tag=sacrifice_valid] run effect @p[r=5] regeneration 10 1 true
execute at @e[type=item,tag=sacrifice_valid] run playsound random.orb @a[r=10] ~ ~ ~ 1.0 1.2
execute at @e[type=item,tag=sacrifice_valid] run particle minecraft:villager_happy ~ ~0.5 ~ 0.3 0.3 0.3 0.1 15

# Destroy the item entity so the reward only triggers once
kill @e[type=item,tag=sacrifice_valid]

Multi-Item Floor Crafting Recipe

When your add-on requires throwing two or more items together on the ground to craft a custom result, you must make sure both items are present before deleting either of them. If you kill the first item too early, or if two stacks of the same item trigger the recipe twice in the same tick, players can lose items without getting their output.

The cleanest command pattern uses one item as the anchor (`@s`) and checks for the second item within a tiny radius (`r=1`). By adding `c=1` (count of 1) when tagging and killing the partner item, you ensure that throwing two sticks and two iron ingots processes one pair per tick rather than deleting all items at once and only spawning a single result.

Note that `kill @e[type=item]` destroys the entire item stack, whether the player threw 1 item or 64 items. With pure commands, there is no way to subtract 1 from a dropped item stack on the ground; if stack-size precision matters, encourage players to drop single items or use the `hasitem` player-inventory method before the drop occurs.

BP/functions/crafting/floor_craft.mcfunction
# Step 1: Find a Blaze Rod that has a Ghast Tear within 1 block of it
execute as @e[type=item,name="Blaze Rod"] at @s if entity @e[type=item,name="Ghast Tear",r=1] run tag @s add craft_anchor

# Step 2: Process only ONE anchor per tick (c=1) to prevent bulk-deletion bugs
execute as @e[type=item,tag=craft_anchor,c=1] at @s run tag @e[type=item,name="Ghast Tear",r=1,c=1] add craft_partner

# Step 3: Only spawn the result if both anchor and partner are locked in
execute at @e[type=item,tag=craft_anchor,c=1] if entity @e[type=item,tag=craft_partner,r=1] run structure load mystructure:custom_wand ~ ~ ~ 0_degrees none true false
execute at @e[type=item,tag=craft_anchor,c=1] if entity @e[type=item,tag=craft_partner,r=1] run particle minecraft:totem_particle ~ ~0.2 ~ 0.2 0.2 0.2 0.1 20
execute at @e[type=item,tag=craft_anchor,c=1] if entity @e[type=item,tag=craft_partner,r=1] run playsound random.anvil_use @a[r=8] ~ ~ ~ 0.8 1.5

# Step 4: Clean up the two consumed ingredient stacks
kill @e[type=item,tag=craft_partner,c=1]
kill @e[type=item,tag=craft_anchor,c=1]

# Step 5: Remove leftover anchor tags so remaining items re-evaluate next tick
tag @e[type=item,tag=craft_anchor] remove craft_anchor

Detecting Who Dropped an Item with hasitem

A common use case is triggering an ability when a player presses the Drop key while holding a specific token item, then immediately returning that token to their inventory. Relying on `@e[type=item,name=...]` alone fails if two players stand close together or if the player renames the token at an anvil.

By combining the `hasitem` selector filter with a tag state machine, you can detect the exact tick a player loses an item from their hotbar or inventory, and verify that an item entity simultaneously spawned within a 2-block radius of that player. This guarantees you know the exact player (`@s`) who dropped the item, and lets you use `replaceitem` or `give` to restore the item and `kill` the dropped entity before anyone else can pick it up.

This technique is completely language-independent for the player side because `hasitem` checks the actual item identifier (such as `minecraft:nether_star` or `my_pack:ability_token`), not the localized display string.

BP/functions/abilities/detect_token_drop.mcfunction
# 1. If a player previously held the token, no longer has it anywhere in their inventory,
#    and a dropped item entity just appeared at their position, they dropped it.
execute as @a[tag=holding_token,hasitem={item=minecraft:nether_star,quantity=0}] at @s if entity @e[type=item,r=2] run tag @s add triggered_drop

# 2. Run the ability for players who triggered the drop
execute as @a[tag=triggered_drop] at @s run effect @s speed 5 2 true
execute as @a[tag=triggered_drop] at @s run playsound mob.enderdragon.flap @a[r=12] ~ ~ ~ 1.0 1.4

# 3. Delete the closest freshly dropped item entity and return the token to the player
execute as @a[tag=triggered_drop] at @s run kill @e[type=item,r=2,c=1]
give @a[tag=triggered_drop] minecraft:nether_star 1 0

# 4. Reset the trigger tag
tag @a[tag=triggered_drop] remove triggered_drop

# 5. Update the state tag for the next tick: only players holding the star in their mainhand are armed
tag @a remove holding_token
tag @a[hasitem={item=minecraft:nether_star,location=slot.weapon.mainhand}] add holding_token

Registering the Detection Function in tick.json

Commands inside `.mcfunction` files do not run automatically unless they are called by an entity event, an animation controller, or the pack's `tick.json` file. Because item drops happen instantaneously and players can pick the item back up within a second, your detection function must run every game tick (20 times per second).

Create `BP/functions/tick.json` and list the path to your `.mcfunction` file relative to the `BP/functions/` folder, without the `.mcfunction` file extension.

BP/functions/tick.json
{
  "values": [
    "altar/check_sacrifice",
    "crafting/floor_craft",
    "abilities/detect_token_drop"
  ]
}

Transitioning to Player Animation Controllers

If you prefer not to run a global `tick.json` check on every player every tick, you can attach a Behavior Pack animation controller to `minecraft:player`. In a two-state controller, the default state waits until `query.is_item_name_any('slot.weapon.mainhand', 0, 'minecraft:nether_star')` is true, then transitions to an `armed` state.

The `armed` state transitions back to `default` when `!query.is_item_name_any('slot.weapon.mainhand', 0, 'minecraft:nether_star')`. On `on_exit` of the `armed` state, you run a single command checking `@s[hasitem={item=minecraft:nether_star,quantity=0}]` alongside `@e[type=item,r=2]`. This ensures the slash commands only execute on the exact frame a player un-equips or drops the item, saving server performance when nobody is holding the special item.

BP/animation_controllers/token_drop.ac.json
{
  "format_version": "1.10.0",
  "animation_controllers": {
    "controller.animation.token_drop": {
      "initial_state": "unarmed",
      "states": {
        "unarmed": {
          "transitions": [
            {
              "armed": "query.is_item_name_any('slot.weapon.mainhand', 0, 'minecraft:nether_star')"
            }
          ]
        },
        "armed": {
          "transitions": [
            {
              "unarmed": "!query.is_item_name_any('slot.weapon.mainhand', 0, 'minecraft:nether_star')"
            }
          ],
          "on_exit": [
            "/execute as @s[hasitem={item=minecraft:nether_star,quantity=0}] at @s if entity @e[type=item,r=2] run function abilities/on_token_dropped"
          ]
        }
      }
    }
  }
}

Which versions this applies to

Applies to Bedrock Edition 1.19.50 and newer (uses the modern `execute as ... at ... if ... run` syntax introduced in 1.19.50 and the `hasitem` selector filter introduced in 1.18.20). No experimental toggles are required.

When it does not work

What you seeWhyThe fix
Syntax error: Unexpected "as": at "execute >>as<< @e[type=item..."Your Behavior Pack's `manifest.json` has `min_engine_version` set below `[1, 19, 50]`. Bedrock locks `.mcfunction` files to the legacy `execute <origin> <position> <command>` syntax unless the manifest explicitly declares 1.19.50 or higher.Open `BP/manifest.json` and update `header.min_engine_version` to at least `[1, 19, 50]` so the parser accepts the modern `execute as/at/if/run` subcommands.
No targets matched selector (when testing `@e[type=item,name="..."]`)You passed the item identifier (like `name="minecraft:diamond"` or `name="redstone"`) instead of the localized display name, or your game client is set to a language other than English.Use the exact in-game hover name of the item in quotes, such as `name="Diamond"` or `name="Redstone Dust"`. For custom items, match the string defined in your Resource Pack's `texts/en_US.lang` file, or switch to the `hasitem` player-tracking method.
Player moves item to another inventory slot or chest and triggers the drop abilityYour `hasitem` check only tested `location=slot.weapon.mainhand` with `quantity=0`, which becomes true as soon as the player swaps hotbar slots or puts the item into their main inventory.Omit the `location` parameter when checking for `quantity=0` (`hasitem={item=...,quantity=0}`) so it checks the entire player inventory and hotbar, and always pair it with `if entity @e[type=item,r=2]` to confirm an item entity actually exists in the world.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.