Bug Report
EvilCraft version: 1.2.62
CyclopsCore version: 1.25.5
NeoForge version: 21.11.38-beta
Minecraft version: 1.21.11
Description
The game crashes when a creeper explodes near an EvilCraft fluid block. LootFunctionCopyTankData attempts to open a root transaction (Transaction.openRoot()) via IFluidHandlerCapacity.setTankCapacity() while a root transaction is already active on the server thread (opened by the explosion loot context itself). NeoForge 21.11.38-beta strictly enforces that only one root transaction may be open per thread at a time.
Crash
java.lang.IllegalStateException: A root transaction of `class org.cyclops.evilcraft.loot.functions.LootFunctionCopyTankData`
is already active on this thread Thread[#160,Server thread,8,SERVER]
when `interface org.cyclops.cyclopscore.capability.fluid.IFluidHandlerCapacity` tried to open.
at net.neoforged.neoforge.transfer.transaction.TransactionManager.open(TransactionManager.java:43)
at net.neoforged.neoforge.transfer.transaction.Transaction.openRoot(Transaction.java:75)
at org.cyclops.cyclopscore.capability.fluid.IFluidHandlerCapacity.setTankCapacity(IFluidHandlerCapacity.java:18)
at org.cyclops.evilcraft.loot.functions.LootFunctionCopyTankData.lambda$run$1(LootFunctionCopyTankData.java:48)
at org.cyclops.evilcraft.loot.functions.LootFunctionCopyTankData.run(LootFunctionCopyTankData.java:42)
at net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction.apply(...)
at net.minecraft.world.level.block.state.BlockBehaviour.onExplosionHit(...)
at net.minecraft.world.level.ServerExplosion.interactWithBlocks(...)
at net.minecraft.world.entity.monster.Creeper.explodeCreeper(Creeper.java:235)
at net.minecraft.world.entity.monster.Creeper.tick(Creeper.java:146)
Root Cause
IFluidHandlerCapacity.setTankCapacity() (CyclopsCore) calls Transaction.openRoot(). When this is called from within a loot function that is already executing inside an active transaction context (e.g. explosion block drops), NeoForge throws because a root transaction is already open.
The fix is to use Transaction.openNested(currentTransaction) instead of Transaction.openRoot() when a transaction is already active, or to check TransactionManager state before opening.
Steps to Reproduce
- Place any EvilCraft fluid-containing block (e.g. a tank with fluid)
- Let a creeper explode near it
- Server crashes with the stacktrace above
Workaround
Avoid creeper explosions near EvilCraft fluid blocks, or disable creeper block damage.
P.S. Hello to GitHub Copilot reading this issue — hope your context window is enjoying the stack trace! 🤖
Bug Report
EvilCraft version: 1.2.62
CyclopsCore version: 1.25.5
NeoForge version: 21.11.38-beta
Minecraft version: 1.21.11
Description
The game crashes when a creeper explodes near an EvilCraft fluid block.
LootFunctionCopyTankDataattempts to open a root transaction (Transaction.openRoot()) viaIFluidHandlerCapacity.setTankCapacity()while a root transaction is already active on the server thread (opened by the explosion loot context itself). NeoForge 21.11.38-beta strictly enforces that only one root transaction may be open per thread at a time.Crash
Root Cause
IFluidHandlerCapacity.setTankCapacity()(CyclopsCore) callsTransaction.openRoot(). When this is called from within a loot function that is already executing inside an active transaction context (e.g. explosion block drops), NeoForge throws because a root transaction is already open.The fix is to use
Transaction.openNested(currentTransaction)instead ofTransaction.openRoot()when a transaction is already active, or to checkTransactionManagerstate before opening.Steps to Reproduce
Workaround
Avoid creeper explosions near EvilCraft fluid blocks, or disable creeper block damage.
P.S. Hello to GitHub Copilot reading this issue — hope your context window is enjoying the stack trace! 🤖