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:
- Place down one stone block surrounded by two non-stone blocks
- Place an armor stand on top of each block
- 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.
Created Issue:
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:
- Place down one stone block surrounded by two non-stone blocks
- Place an armor stand on top of each block
- 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 ~ stoneThe 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.
Windows 10
Java 1.8.0_25 64Bit
Having an execute running as multiple entities will cancel for the rest of the entities if one of these fails.
Steps to reproduce:
- Place down one stone block surrounded by two non-stone blocks
- Place an armor stand on top of each block
- 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 ~ stoneThe 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.
Having an execute running as multiple entities will cancel for the rest of the entities if one of these fails.
Steps to reproduce:
- Place down one stone block surrounded by two non-stone blocks
- Place an armor stand on top of each block
- 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 ~ stoneThe 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.
Windows 10
Java 1.8.0_25 64Bit
To start off with, this bug is the reason, why MC-121727 is open again. Somebody commented it below there and it got reopened, even though this is actually a slightly different problem and belongs in its own bug report. I will post a comment under that report as well, linking to this, so that it gets closed again as resolved.
As explained in the title, even though if and unless are checked for every entity, only if all conditions are met it will execute the command for each entity.
Example:
- Place down two armor stands on top of two stone blocks
- Run the following command:
/execute as @e[type=armor_stand] at @s if block ~ ~-1 ~ stone run say hi - Both armor stands will say hi, which is correct
- Change the block below one armor stand with something different and run the command again
- This time, no text will appear in the chat, as only one of the two conditions were met
I for myself doubt, that this is the intended behavior, but even if it is, the following command should work nonetheless:
/execute as @e[type=armor_stand] at @s run execute if block ~ ~-1 ~ stone run say hi
By nesting the execute, the two nested execute-calls should be completely isolated from each other. This is not the case though, as it yields the exact same result, as without the nesting.
This implies, that nested executes will get optimized into one execute.
If you put the conditional execute into a function, and run that function, instead of having the execute inlined, it does work as you would have expected it with the nested execute, as those two function calls are completely isolated from each other now.
This all got a bit long... The huge and-gate was probably never intended, which would make the execute optimization valid as well.
VERY IMPORTANT additional information I found, after taking a look at the dupe MC-122821:
As it turns out, not only if and unless cause this and-behavior to happen and they are actually not the core reason for this to happen at all. The reason is something more simple, which can be shown by a simple example:
execute as @e[type=armor_stand] as @s[tag=test] run say hi
You might think this example yields the same output as this example:
execute as @e[type=armor_stand,tag=test] run say hi
but it does not and again, only if all armor stands have the test tag it will, and if not, nothing will happen. The reason is, that the first as sub-command only runs for all entities, if it can successfully run the next sub-command in line (not including the final run command, except for nested executes, as those get optimized into one execute...) for each of those entities.
This means, only if the @s[tag=test] returns at least one entity, for each entity of the first sub-command, the command will do something. In other words, if (at least) one armor stand does not have the tag test, not all armor stands could successfully execute a command and therefore no armor stand will.
Going to change the title to something more fitting shortly.
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 ~ dirtdoes the exact same thing as
execute as @e[type=armor_stand] at @s run execute if block ~ ~-1 ~ stone run setblock ~ ~-1 ~ dirtand 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 ~ dirtand run it via
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-121934This 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.