Wiki 9Minecraft Wiki 9Minecraft

Command Differences That Catch Java Players Out

How Bedrock's command syntax, selectors, and lack of NBT affect add-on and function creators.

6Sections
3Code examples
4Known errors

If you are porting a data pack from Java Edition or writing your first Bedrock `.mcfunction` files, your muscle memory will work against you. While Bedrock shares many core command names and the modern `/execute` syntax with Java, the underlying architecture is completely different. Understanding where NBT went, how block states are formatted, and how target selectors differ will save you hours of debugging silent function failures.

The Biggest Hurdle: No Direct NBT Access

The single biggest shock for a Java command creator moving to Bedrock is the complete absence of raw NBT manipulation in commands. In Java Edition, commands like `/data get`, `/data merge`, and inline `{Tags:["my_tag"],CustomName:'"Bob"'}` payloads are the backbone of almost every data pack. In Bedrock Edition, you cannot read or write raw entity, block, or item NBT strings through commands.

Instead of modifying an existing entity's NBT on the fly, Bedrock expects you to define behaviors inside an entity's behavior pack JSON file using component groups and events. To change what an entity does, is named, or looks like from a command, you fire an entity event using `/event entity @e[type=...] my_pack:some_event` or summon the entity with a birth event directly in `/summon`.

Commands do still allow a curated, strict subset of item JSON components at the end of `/give`, `/replaceitem`, and `/clear`. These are limited to four specific properties: `minecraft:can_place_on`, `minecraft:can_destroy`, `minecraft:item_lock`, and `minecraft:keep_on_death`. You cannot use `/give` to grant a sword with custom lore, a custom display name, or custom enchantments via JSON strings; for those tasks, you must either use the Script API (`@minecraft/server`) or load a saved structure containing the modified item using `/structure load`.

This architectural split means that pure command creations in Bedrock are much more tightly coupled to behavior pack JSON files and TypeScript than Java data packs are. When you find yourself asking how to test for a specific NBT tag on a player or mob, the Bedrock answer is almost always to use entity properties, scoreboard objectives, `/tag`, or the `hasitem` selector argument.

BP/entities/custom_guard.json
{
  "format_version": "1.20.40",
  "minecraft:entity": {
    "description": {
      "identifier": "wiki:custom_guard",
      "is_spawnable": true,
      "is_summonable": true
    },
    "component_groups": {
      "wiki:hostile_mode": {
        "minecraft:behavior.nearest_attackable_target": {
          "priority": 2,
          "must_see": true,
          "entity_types": [
            {
              "filters": {
                "test": "is_family",
                "subject": "other",
                "value": "player"
              },
              "max_dist": 16
            }
          ]
        }
      }
    },
    "components": {
      "minecraft:type_family": {
        "family": ["guard", "mob"]
      },
      "minecraft:health": {
        "value": 20,
        "max": 20
      }
    },
    "events": {
      "wiki:become_hostile": {
        "add": {
          "component_groups": ["wiki:hostile_mode"]
        }
      }
    }
  }
}

Target Selectors and Arguments

Bedrock target selectors (`@p`, `@a`, `@r`, `@e`, `@s`) look very familiar at first glance, and there is even a dedicated `@initiator` selector used specifically in NPC dialogue commands to target the player who clicked the NPC. However, the arguments inside the square brackets differ sharply from Java Edition. Using a Java selector argument in a Bedrock `.mcfunction` file will cause the entire function file to fail parsing on world load.

The most common trap is distance and sorting. Java uses `distance=..5` (a range operator) and `sort=nearest,limit=1`. Bedrock retains the older, separated min/max arguments and uses `c` (count) instead of `limit` or `sort`. To select the closest 3 zombies within 5 to 10 blocks in Bedrock, you write `@e[type=zombie,r=10,rm=5,c=3]`. If you pass a negative number to `c`, such as `c=-1`, it reverses the sort order and targets the furthest matching entity instead of the nearest.

Because there is no `nbt={Inventory:[...]}` selector in Bedrock, checking player or entity inventories is handled through the `hasitem` selector argument. This is a remarkably powerful Bedrock-exclusive feature that accepts either a single condition block or an array of conditions. You can check for specific item identifiers, item data values, quantities (which DO support the `..` range syntax, unlike `r`), and specific equipment or container slots.

Scoreboard filtering is nearly identical to Java, using `scores={my_obj=1..5}`. Note that `..` ranges work inside `scores` and `hasitem`, as well as the `has_property` selector filter, even though they do not work for radius (`r`/`rm`), levels (`l`/`lm`), or rotation (`rx`/`rxm`, `ry`/`rym`). Additionally, Bedrock allows the `!` negation operator on several arguments where Java requires different workarounds, such as `type=!player,type=!item`.

Java Selector ArgumentBedrock EquivalentNotes
distance=5..10rm=5,r=10Bedrock uses separate radius minimum (rm) and radius maximum (r) arguments.
limit=1,sort=nearestc=1Count (c) defaults to nearest for @p and @e. Use a negative integer (c=-1) to select the furthest.
level=10..20lm=10,l=20Level minimum (lm) and level maximum (l) are separate arguments.
x_rotation=-45..45rxm=-45,rx=45Vertical rotation uses rxm and rx; horizontal rotation uses rym and ry.
nbt={Inventory:[...]}hasitem={item=...,location=...,slot=...}Supports checking mainhand, offhand, armor slots, hotbar, and general inventory.
team=redNone (use tag=team_red or family=...)Vanilla Bedrock does not have a /team command. Creators use tags or type_family filters instead.

The Modern /execute Command and Its Missing Pieces

Wait-list tutorials from before 2022 will warn you that Bedrock uses the old pre-1.13 `/execute @e ~ ~ ~` syntax. That is no longer true. As of format version 1.19.50 and newer, Bedrock uses the chained `/execute as ... at ... run ...` syntax brought over from Java Edition. If you are writing new `.mcfunction` files today, your `min_engine_version` in `manifest.json` should be at least `[1, 19, 50]` (ideally current stable) so that your functions parse with the modern `/execute` syntax.

While `as`, `at`, `in`, `positioned`, `rotated`, `facing`, `align`, `anchored`, `if`, and `unless` all work the way a Java developer expects, there is one massive omission: **`execute store` does not exist in Bedrock**. In Java, `execute store result score` is how you capture the return value of a command (like how many players matched a selector, how many items `/clear` removed, or a player's current health) into a scoreboard objective.

Because `execute store` is missing, you cannot easily pipe the output of `/testfor` or `/clear` into a scoreboard using pure commands. To count matching entities in pure commands, you instead run `/execute as @e[type=zombie] run scoreboard players add #count my_obj 1` after resetting `#count` to zero. For reading entity health, coordinates, or inventory counts into a scoreboard, Bedrock add-on creators rely on Molang queries inside behavior pack animations/controllers or a few lines of JavaScript using `@minecraft/server`.

One other minor difference in `/execute`: in Bedrock, the slash `/` before the subcommand following `run` is optional in chat, though standard practice in `.mcfunction` files is to omit leading slashes entirely on every line, including after `run`.

BP/manifest.json
{
  "format_version": 2,
  "header": {
    "name": "Modern Execute Pack",
    "description": "Requires min_engine_version 1.19.50+ for new execute syntax in functions",
    "uuid": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
    "version": [1, 0, 0],
    "min_engine_version": [1, 20, 80]
  },
  "modules": [
    {
      "type": "data",
      "uuid": "b2c3d4e5-f6a7-4b5c-9d0e-1f2a3b4c5d6e",
      "version": [1, 0, 0]
    }
  ]
}

Block States Syntax in Commands

Since Bedrock 1.19.70 and the ongoing flattening of block IDs, numeric data values (like `/setblock ~ ~ ~ stone 1`) have been replaced by explicit block states. While both Java and Bedrock now use square brackets `[]` right after the block identifier in `/setblock`, `/fill`, `/testforblock`, and `execute if block`, the formatting inside those brackets is stricter in Bedrock.

In Java Edition, block state keys and values are unquoted strings separated by an equals sign, such as `minecraft:oak_log[axis=y]` or `minecraft:lit_furnace[facing=north,lit=true]`. In Bedrock Edition, block state names are always enclosed in double quotes `""`, and string values are also enclosed in double quotes. Furthermore, until recent updates unified the separator, Bedrock originally used a colon `:` instead of `=`; modern Bedrock now requires the `=` sign just like Java, but keeps the mandatory quotes around string keys and string values.

Boolean values (`true` and `false`) and integer values (`0`, `1`, `2`) inside Bedrock block states are NOT quoted, whereas string values (`"north"`, `"y"`, `"bottom"`) ARE quoted. Getting this wrong is one of the most frequent causes of syntax errors when porting `/fill` or `/setblock` commands. Additionally, many block state names themselves differ between the two editions: Java's `axis=y` on logs is `"pillar_axis"="y"` in Bedrock, and Java's `facing=north` is often `"minecraft:cardinal_direction"="north"` or `"facing_direction"=2` depending on when the block was introduced.

If you leave the square brackets empty (`minecraft:oak_log[]`) or omit them entirely (`minecraft:oak_log`), Bedrock places the block with its default states. When using `execute if block ~ ~ ~ minecraft:chest ["minecraft:cardinal_direction"="north"]`, you only need to specify the states you actually care about testing; unspecified states act as wildcards.

TaskJava Edition SyntaxBedrock Edition Syntax
Place horizontal oak logsetblock ~ ~ ~ oak_log[axis=x]setblock ~ ~ ~ oak_log["pillar_axis"="x"]
Place upper stone slabsetblock ~ ~ ~ stone_slab[type=top]setblock ~ ~ ~ normal_stone_slab["minecraft:vertical_half"="top"]
Test for open oak trapdoorexecute if block ~ ~ ~ oak_trapdoor[open=true]execute if block ~ ~ ~ trapdoor["open_bit"=true]
Place repeater with 3-tick delaysetblock ~ ~ ~ repeater[delay=3]setblock ~ ~ ~ unpowered_repeater["repeater_delay"=2]

Inventory, Scoreboards, and Bedrock-Exclusive Commands

When modifying inventories, Java creators reach for `/item replace` (which replaced `/replaceitem` in Java 1.17). Bedrock still uses `/replaceitem block` and `/replaceitem entity`. One quirk of Bedrock's `/replaceitem` is that slot numbering and slot names are slightly different: armor slots are individually named (`slot.armor.head`, `slot.armor.chest`, `slot.armor.legs`, `slot.armor.feet`), the offhand is `slot.weapon.offhand`, and `/replaceitem` has an optional `oldItemHandling` mode (`destroy` or `keep`) right before the item name that allows you to avoid overwriting existing items in a slot.

For scoreboards, Bedrock only supports the `dummy` criteria in `/scoreboard objectives add`. In Java, you can create objectives that automatically track `minecraft.custom:minecraft.jump`, `health`, `deathCount`, or `minecraft.mined:minecraft.stone`. None of those automatic criteria exist in Bedrock. Every scoreboard objective in Bedrock is a `dummy` objective, and you must update it manually via commands, animation controllers, or Script API events. On the bright side, Bedrock includes `/scoreboard players random <player> <objective> <min> <max>`, a built-in RNG command that Java creators have had to build math libraries to replicate.

Finally, Bedrock includes a suite of presentation and gameplay commands that have no direct command equivalent in earlier Java versions or work much more simply in Bedrock. `/camera` allows smooth cinematic camera splines and third-person presets without spectator-entity riding hacks; `/hud` lets you hide and show specific vanilla HUD elements like the hunger bar, crosshair, or paperdoll per player; `/inputpermission` can lock a player's movement or camera rotation cleanly without teleport loops; and `/playanimation` can fire any resource pack animation on any entity on demand.

How tick.json Replaces function Tag Files

In a Java data pack, to make a function run every game tick or on world load, you place a JSON file at `data/minecraft/tags/function/tick.json` or `load.json`. In a Bedrock behavior pack, there is no `load.json` equivalent in pure functions, and ticking functions are registered in a single file located at `BP/functions/tick.json`.

The format of `BP/functions/tick.json` is a simple JSON object containing a `values` array of function paths relative to the `BP/functions/` folder (without the `.mcfunction` extension). Any function listed here will execute 20 times per second at the world spawn coordinates, with the server itself as the execution context (`@s` is null, and `~ ~ ~` is `0 0 0` or the world spawn depending on context, so always specify `at` or `positioned` inside your functions).

BP/functions/tick.json
{
  "values": [
    "main_loop",
    "systems/check_players"
  ]
}

Which versions this applies to

Applies to Bedrock Edition 1.19.70 through 1.21+ (requires min_engine_version 1.19.50 or higher in manifest.json to use modern /execute syntax and current block state formatting in .mcfunction files). No experimental toggles are required for any commands covered on this page.

When it does not work

What you seeWhyThe fix
Function file completely disappears from the `/function` autocomplete list in-game, or Content Log shows: `Function <name> failed to load correctly with error(s): Syntax error: Unexpected ".": at "distance=>>.<<.5"`If even a single line in a `.mcfunction` file has invalid Bedrock syntax (such as using Java's `distance=..5`, `limit=1`, or unquoted block states), Bedrock refuses to register the entire `.mcfunction` file on world load.Enable the Content Log GUI in Creator Settings, reload the world, and check the exact line number reported. Replace Java selector arguments with their Bedrock equivalents (`r=`, `rm=`, `c=`).
Commands inside `.mcfunction` files fail with `Syntax error: Unexpected "as": at "execute >>as<< @a"`, even though `/execute as @a` works when typed directly into the in-game chat.Your behavior pack's `manifest.json` has a `min_engine_version` lower than `[1, 19, 50]` (or is missing `min_engine_version` entirely). For backwards compatibility, Bedrock parses function files in older packs using the legacy pre-1.19.50 `/execute @a ~ ~ ~` syntax.Open `BP/manifest.json` and update `min_engine_version` inside the `header` object to `[1, 20, 80]` or your current target game version.
`/setblock` or `/fill` fails with `Syntax error: Unexpected "axis": at "oak_log[>>axis<<=x]"` or `BlockState 'axis' is not defined on block 'minecraft:oak_log'`.You used unquoted block state keys/values or Java Edition block state names.Wrap block state keys and string values in double quotes, and verify the Bedrock state name. For example, change `oak_log[axis=x]` to `oak_log["pillar_axis"="x"]`.
`/give @s diamond_sword 1 0 {"display":{"Name":"Excalibur"}}` fails with a JSON component error stating only specific components are supported.Bedrock's `/give` and `/replaceitem` commands only accept `minecraft:can_place_on`, `minecraft:can_destroy`, `minecraft:item_lock`, and `minecraft:keep_on_death` in their trailing JSON object.To give an item with a custom name, lore, or enchantments via commands, rename and enchant the item in-game, save it inside a 1x1x1 structure using a Structure Block (or `/structure save` with entities enabled around a dropped item), and give it to players by running `/execute at @s run structure load my_item:excalibur ~ ~ ~`.

Reference, straight from the game files

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