Skip to content

Fix NPE when a minion breaks the magic block (#525)#526

Merged
tastybento merged 1 commit into
developfrom
fix/525-minion-magic-block
Jul 3, 2026
Merged

Fix NPE when a minion breaks the magic block (#525)#526
tastybento merged 1 commit into
developfrom
fix/525-minion-magic-block

Conversation

@tastybento

Copy link
Copy Markdown
Member

Fixes #525

Problem

When the JetsMinions Miner minion (an armor stand) breaks the magic block, the block disappears and never respawns, and the console logs an NPE. It must be restored manually with /ob respawnBlock.

java.lang.NullPointerException: Cannot invoke "world.bentobox.bentobox.api.user.User.getMetaData(String)" because "this.user" is null
	at ...FlagListener.hasBypassEverywhere(FlagListener.java:216)
	at ...FlagListener.checkIsland(FlagListener.java:179)
	at ...BlockListener.process(BlockListener.java:354)
	at ...BlockListener.lambda$onBlockBreakByMinion$1(BlockListener.java:249)

Root cause

onBlockBreakByMinion calls process(...) with player == null (a minion has no player). process then called BentoBox's checkIsland(event, null, ...), which sets user = null and later dereferences it in hasBypassEverywhere → NPE. The handler aborts before the block can respawn.

This is why the issue only appears from 1.22.0 onward — that release introduced the MAGIC_BLOCK protection flag and thus this checkIsland call. Earlier versions never ran the flag check on the minion path.

Fix

Skip the protection-flag check when there is no player:

if (player != null && !checkIsland((@NonNull Event) e, player, island.getCenter(), addon.MAGIC_BLOCK)) {
    return;
}

The flag check evaluates a user's permissions; there is no user for a minion, so it cannot apply. This restores the pre-1.22.0 minion behaviour while keeping full protection for real players. It's also consistent with the existing "minions cannot fulfill requirements" branch in CheckPhase.phaseRequirementsFail.

Testing

Added testOnBlockBreakByMinionProcessesWithoutPlayer in BlockListenerTest2, which asserts a minion break no longer throws and processing continues past the flag check into phase handling (so the block respawns). All BlockListener tests pass.

🤖 Generated with Claude Code

When a JetsMinions Miner (an armor stand) breaks the magic block,
process() was called with a null player and passed it into BentoBox's
checkIsland(). That sets user = null and later dereferences it in
hasBypassEverywhere(), throwing an NPE. The event handler aborted before
the block could respawn, forcing a manual /ob respawnBlock.

The bug appeared in 1.22.0 when the MAGIC_BLOCK protection flag (and thus
this checkIsland call) was added; before then the minion path never
touched the flag system.

Skip the protection-flag check when there is no player. The check
evaluates a user's permissions, and there is no user for a minion, so it
cannot apply. This restores the pre-1.22.0 minion behaviour while keeping
full protection for real players, and dovetails with the existing
"minions cannot fulfill requirements" branch in CheckPhase.

Adds a regression test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014HVDpBn8egQPccyYsLFZvi
@sonarqubecloud

sonarqubecloud Bot commented Jul 3, 2026

Copy link
Copy Markdown

@tastybento tastybento merged commit c19d6aa into develop Jul 3, 2026
3 checks passed
@tastybento tastybento deleted the fix/525-minion-magic-block branch July 3, 2026 17:18
@tastybento tastybento mentioned this pull request Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JetsMinions Miner minion breaks magic block

1 participant