mojira.dev
MC-121727

execute on multiple entites cancels, once one command fails

Having an execute running as multiple entities will cancel for the rest of the entities if one of these fails.

Steps to reproduce:

  1. Place down one stone block surrounded by two non-stone blocks

  2. Place an armor stand on top of each block

  3. Run the following command while standing on the left of the line:

    execute as @e[type=armor_stand,sort=nearest] at @s run setblock ~ ~-1 ~ stone

The expected behavior would be, that it will place stone under the two armor stands on the sides and leave the stone in the middle as is. This is not the case, because a setblock, that doesn't change anything (stone->stone) will fail and cancel the execute. Only one of the two stones got set.

Furthermore, but this belongs to a separate bug-report, the order, that execute processes each entity is in my eyes in reverse. Even though nearest was specified, the further armor stand sets its block first, before the middle one canceled the rest of the execute.

Comments 4

So i tried this command

execute as @e[tag=crafter] at @s if block ~ ~-1 ~ minecraft:dropper[facing=up]{Items:[{Slot:4b,id:"minecraft:diamond",Count:1b}]} run data merge block ~ ~-1 ~ {Items:[{Slot:4b,id:"minecraft:coal",Count:1b}]}

in theory it should replace every diamond in the dropper under the armor stand with 1 coal. And yes it does, but only if every armor stand has an diamond in the dropper below. What i expect is that only the armor stand wich hast the diamond in the dropper replaces the diamond with 1 coal and not every armor stand.

It seems, like the if gets evaluated for all armor stands first, and only if all conditions are met, the run part of the execute gets called (for each armor stand of course).

So I thought, if you put the block-detection into a separate, nested execute it would work, but it gives the exact same result. There might be either some faulty optimization, where the nested execute got optimized into the first execute or it was never supposed to be like this, and the if was meant to be checked for each selector-list item.

Put into commands, what I mean is, that

execute as @e[type=armor_stand] at @s if block ~ ~-1 ~ stone run setblock ~ ~-1 ~ dirt

does the exact same thing as

execute as @e[type=armor_stand] at @s run execute if block ~ ~-1 ~ stone run setblock ~ ~-1 ~ dirt

and they both only run the final command for each entity if the if was true for each entity.

Dinnerbone should take a look at this, as to how he intended this in the first place. At the moment it seems like the system is somewhat flawed in either of those two ways.

A small followup:

If you create a function test:test with the content:

execute if block ~ ~-1 ~ stone run setblock ~ ~-1 ~ dirt

and run it via

execute as @e[type=armor_stand] at @s run function test:test

it does work, as the the nested execute doesn't get merged with the parent execute and therefore handle the if for each separate function call.

Because the last few comments aren't actually related to the bug report completely, I created a new ticket: MC-121934

This ticket can be marked as closed again, as the bug described in this report is fixed and the comments are actually related to the new bug report.

Possseidon

Nathan Adams

Confirmed

/execute

Minecraft 17w45a

Minecraft 17w45b

Retrieved