Repository navigation
[Bug] Sable (1.2.2) mixins crash world permanently on null Create block entity state (DeployerBlockEntityMixin & PipeConnectionMixin so far) #675
Description
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:deployerblock 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_pipecarrying 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
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: 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.
Activity