Description
[Bug] Sable mixins crash world on null block entity state — Create deployer & CannonCast (Create Big Cannons)
Summary
Sable's Create-compatibility mixins (DeployerBlockEntityMixin and PipeConnectionMixin) do not perform null checks before accessing block entity internals. When a Create block entity is in a partially broken or uninitialized state, Sable's tick interception causes a NullPointerException that permanently crashes the world — the game crashes every tick from that point forward, making the world unloadable until the offending block entity is manually removed via an external world editor.
Two separate crashes were observed, both caused by the same underlying pattern.
Environment
| Field |
Value |
| Minecraft |
1.21.1 |
| NeoForge |
21.1.222 |
| Sable |
1.2.2 (sable-neoforge-1.21.1-1.2.2.jar) |
| Create |
6.0.10 |
| Create Big Cannons |
5.11.2 |
| Create Aeronautics (bundled) |
1.2.1 |
| OS |
Windows 11 (amd64) |
| Java |
21.0.7 (Microsoft OpenJDK) |
Crash #1 — DeployerBlockEntityMixin / null fake player
What happened
A create:deployer block entity existed in the world. On world load, Sable's DeployerBlockEntityMixin attempts to access be.player (the deployer's fake player) before it has been initialized, resulting in a NullPointerException. The crash occurs on the first server tick, before any commands can be run.
Stack trace (abridged)
java.lang.NullPointerException: Cannot invoke "DeployerFakePlayer.getMainHandItem()"
because "be.player" is null
at TRANSFORMER/sable@1.2.2/.../DeployerBlockEntityMixin (...)
at TRANSFORMER/createbigcannons@5.11.2/.../DeployerBlockEntity (...)
Affected block entity
Name: create:deployer
Block location: World: (1162, 94, 781)
Region: r.2.1.mca
Reproduction steps
- Place a
create:deployer block in the world.
- Ensure Sable 1.2.2 is installed.
- Reload the world (e.g. via waystone teleport or relog).
- World crashes immediately on the first tick.
Crash #2 — PipeConnectionMixin / null CannonCast controller
What happened
A create:fluid_pipe block entity was ticking and scanning adjacent blocks for fluid capability. One adjacent block was a createbigcannons:cannon_cast block entity whose multiblock controller had become null (the controller reference was lost during the casting solidification process). Sable's PipeConnectionMixin intercepts PipeConnection.determineSource(), which calls into the NeoForge capability system, which in turn invokes the CannonCast's capability handler — getHandlerForCap() — which calls getControllerBE(), which returns null. No null check exists before dereferencing it.
Stack trace (abridged)
java.lang.NullPointerException: Cannot invoke
"CannonCastBlockEntity.getHandlerForCap()"
because the return value of "CannonCastBlockEntity.getControllerBE()" is null
at createbigcannons@5.11.2 / CannonCastBlockEntity.getHandlerForCap (CannonCastBlockEntity.java:64)
at createbigcannons@5.11.2 / CannonCastBlockEntity.lambda$onRegisterCapabilities$0 (CannonCastBlockEntity.java:47)
at neoforge@21.1.222 / RegisterCapabilitiesEvent.lambda$registerBlockEntity$1 (RegisterCapabilitiesEvent.java:66)
at neoforge@21.1.222 / BlockCapability.getCapability (BlockCapability.java:215)
at create@6.0.10 / FluidPropagator.hasFluidCapability (FluidPropagator.java:207)
at create@6.0.10 / PipeConnection.determineSource (PipeConnection.java:178)
[pl:mixin:APP:sable-neoforge.mixins.json:compatibility.create.fluid_handling.PipeConnectionMixin]
at create@6.0.10 / PipeConnection.manageSource (PipeConnection.java:86)
[pl:mixin:APP:sable-neoforge.mixins.json:compatibility.create.fluid_handling.PipeConnectionMixin]
at create@6.0.10 / FluidTransportBehaviour.tick (FluidTransportBehaviour.java:91)
Affected block entities
Crashing ticker: create:fluid_pipe
Block location: World: (1235, 108, 805)
Region: r.2.1.mca
Root cause: createbigcannons:cannon_cast (adjacent block, controller == null)
Reproduction steps
- Set up a Create Big Cannons casting setup (casting basin + casting sand + cannon cast mold).
- Connect a
create:fluid_pipe carrying molten metal adjacent to the casting setup.
- Fill the mold with molten steel and wait for it to solidify.
- During or after solidification, the cannon cast loses its controller reference.
- On the next tick, the fluid pipe's
PipeConnectionMixin-intercepted tick crashes the game.
- World is unloadable from this point forward.
Root cause analysis
Both crashes share the same pattern:
- A Create block entity ends up in a state where a key internal reference is
null (either the deployer's fake player, or the cannon cast's multiblock controller).
- Sable's mixins intercept the relevant Create tick/capability path without checking for null before dereferencing those references.
- The
NullPointerException propagates up through the server tick loop and crashes the game permanently.
The crashes are not caused by Create or Create Big Cannons in isolation — both mods handle these null states gracefully on their own. The crashes only occur when Sable's mixins intercept the tick path and attempt to access uninitialized state.
Suggested fix
Add null guards in the two affected mixins before accessing block entity internals:
DeployerBlockEntityMixin: Check be.player != null before invoking any method on it.
PipeConnectionMixin: When hasFluidCapability returns a capability handler, check that the handler itself is non-null and in a valid state before proceeding, OR let the capability resolution fail gracefully without the mixin intercepting it in a way that prevents normal null handling.
Game Log
https://mclo.gs/0ctSMcy
Description
[Bug] Sable mixins crash world on null block entity state — Create deployer & CannonCast (Create Big Cannons)
Summary
Sable's Create-compatibility mixins (
DeployerBlockEntityMixinandPipeConnectionMixin) do not perform null checks before accessing block entity internals. When a Create block entity is in a partially broken or uninitialized state, Sable's tick interception causes aNullPointerExceptionthat permanently crashes the world — the game crashes every tick from that point forward, making the world unloadable until the offending block entity is manually removed via an external world editor.Two separate crashes were observed, both caused by the same underlying pattern.
Environment
sable-neoforge-1.21.1-1.2.2.jar)Crash #1 — DeployerBlockEntityMixin / null fake player
What happened
A
create:deployerblock entity existed in the world. On world load, Sable'sDeployerBlockEntityMixinattempts to accessbe.player(the deployer's fake player) before it has been initialized, resulting in aNullPointerException. The crash occurs on the first server tick, before any commands can be run.Stack trace (abridged)
Affected block entity
Reproduction steps
create:deployerblock in the world.Crash #2 — PipeConnectionMixin / null CannonCast controller
What happened
A
create:fluid_pipeblock entity was ticking and scanning adjacent blocks for fluid capability. One adjacent block was acreatebigcannons:cannon_castblock entity whose multiblock controller had become null (the controller reference was lost during the casting solidification process). Sable'sPipeConnectionMixininterceptsPipeConnection.determineSource(), which calls into the NeoForge capability system, which in turn invokes the CannonCast's capability handler —getHandlerForCap()— which callsgetControllerBE(), which returns null. No null check exists before dereferencing it.Stack trace (abridged)
Affected block entities
Reproduction steps
create:fluid_pipecarrying molten metal adjacent to the casting setup.PipeConnectionMixin-intercepted tick crashes the game.Root cause analysis
Both crashes share the same pattern:
null(either the deployer's fake player, or the cannon cast's multiblock controller).NullPointerExceptionpropagates up through the server tick loop and crashes the game permanently.The crashes are not caused by Create or Create Big Cannons in isolation — both mods handle these null states gracefully on their own. The crashes only occur when Sable's mixins intercept the tick path and attempt to access uninitialized state.
Suggested fix
Add null guards in the two affected mixins before accessing block entity internals:
DeployerBlockEntityMixin: Checkbe.player != nullbefore invoking any method on it.PipeConnectionMixin: WhenhasFluidCapabilityreturns a capability handler, check that the handler itself is non-null and in a valid state before proceeding, OR let the capability resolution fail gracefully without the mixin intercepting it in a way that prevents normal null handling.Game Log
https://mclo.gs/0ctSMcy