Skip to content

[Bug] Sable (1.2.2) mixins crash world permanently on null Create block entity state (DeployerBlockEntityMixin & PipeConnectionMixin so far) #675

@mrbloxnnb

Description

@mrbloxnnb

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

  1. Place a create:deployer block in the world.
  2. Ensure Sable 1.2.2 is installed.
  3. Reload the world (e.g. via waystone teleport or relog).
  4. 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

  1. Set up a Create Big Cannons casting setup (casting basin + casting sand + cannon cast mold).
  2. Connect a create:fluid_pipe carrying molten metal adjacent to the casting setup.
  3. Fill the mold with molten steel and wait for it to solidify.
  4. During or after solidification, the cannon cast loses its controller reference.
  5. On the next tick, the fluid pipe's PipeConnectionMixin-intercepted tick crashes the game.
  6. World is unloadable from this point forward.

Root cause analysis

Both crashes share the same pattern:

  1. 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).
  2. Sable's mixins intercept the relevant Create tick/capability path without checking for null before dereferencing those references.
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions