Skip to content

fix: prevent NullPointerException in world setup when getWorld returns null - #4901

Open
bastigfz wants to merge 1 commit into
IntellectualSites:mainfrom
bastigfz:fix/setup-world-npe-v2
Open

fix: prevent NullPointerException in world setup when getWorld returns null#4901
bastigfz wants to merge 1 commit into
IntellectualSites:mainfrom
bastigfz:fix/setup-world-npe-v2

Conversation

@bastigfz

Copy link
Copy Markdown

Description

Fixes a NullPointerException that occurs during /plot setup when BukkitUtil.getSpawn() is called for a world that has not yet been registered with Bukkit.

Root Cause

BukkitUtil.getSpawn() called getWorld(world).getSpawnLocation() without a null check. During the plot setup process, the world may not yet be available via Bukkit.getWorld(), causing:

java.lang.NullPointerException: Cannot invoke "org.bukkit.World.getSpawnLocation()"
because the return value of "com.plotsquared.bukkit.util.BukkitUtil.getWorld(String)" is null
  at BukkitUtil.getSpawn(BukkitUtil.java:318)
  at CommonSetupSteps.java:231

Fix

Added a null check in BukkitUtil.getSpawn(), returning a safe fallback spawn location at (0, 64, 0) when the world is not yet available. This is consistent with the existing null-safe pattern already used in setSpawn().

Related

Copilot AI review requested due to automatic review settings July 15, 2026 11:54
@bastigfz
bastigfz requested a review from a team as a code owner July 15, 2026 11:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes /plot setup failing with an exception when BukkitUtil.getSpawn() is invoked for a world that is not yet registered in Bukkit.

Changes:

  • Adds a null-check around getWorld(world) in BukkitUtil.getSpawn().
  • Introduces a fallback spawn location when the Bukkit world is unavailable.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

final org.bukkit.Location temp = getWorld(world).getSpawnLocation();
final World bukkitWorld = getWorld(world);
if (bukkitWorld == null) {
return Location.at(world, 0, 64, 0);
Copilot AI review requested due to automatic review settings July 15, 2026 11:59
@bastigfz
bastigfz force-pushed the fix/setup-world-npe-v2 branch 2 times, most recently from 1043eb6 to 222222f Compare July 15, 2026 11:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +319 to +323
final World bukkitWorld = getWorld(world);
if (bukkitWorld == null) {
return UncheckedWorldLocation.at(world, 0, 64, 0);
}
final org.bukkit.Location temp = bukkitWorld.getSpawnLocation();
@SirYwell

Copy link
Copy Markdown
Member

During the plot setup process, the world may not yet be available via Bukkit.getWorld()

Why is that?

…s null

BukkitUtil.getSpawn() assumed getWorld() would never return null, but
during the /plot setup process the world may not yet be registered with
Bukkit when getSpawn() is called, causing a NullPointerException.

This adds a null check in getSpawn(), returning a safe fallback spawn
location at (0, 64, 0) when the world is not yet available, consistent
with the existing null-safe pattern used in setSpawn().

Uses UncheckedWorldLocation for the fallback to avoid a secondary
exception from Location.at() which resolves the platform world
internally and throws if the world is not registered.

Also adds a null check in BukkitPlayer.teleport() to prevent a
NullPointerException when constructing the Bukkit Location from a
world that is not yet registered.

Fixes the following error during /plot setup:
java.lang.NullPointerException: Cannot invoke
"org.bukkit.World.getSpawnLocation()" because the return value of
"com.plotsquared.bukkit.util.BukkitUtil.getWorld(String)" is null
Copilot AI review requested due to automatic review settings July 15, 2026 12:07
@bastigfz
bastigfz force-pushed the fix/setup-world-npe-v2 branch from 222222f to 79f9d25 Compare July 15, 2026 12:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@MattBDev

Copy link
Copy Markdown
Contributor

I've never encountered this. I'm going to look into this before approving.

@bastigfz

bastigfz commented Jul 15, 2026

Copy link
Copy Markdown
Author

Why is that?

@SirYwell

The issue occurs because BukkitSetupUtils.setupWorld() calls worldManager().handleWorldCreation(...) which may create the world asynchronously (e.g. via Multiverse or Paper world creation). After that call, Bukkit.getWorld(world) can still be null, but setupWorld() returns the world name anyway:

Objects.requireNonNull(PlotSquared.platform()).worldManager()
        .handleWorldCreation(builder.worldName(), builder.generatorName());

if (Bukkit.getWorld(world) != null) {
    return world;
}

return builder.worldName();

Back in CHOOSE_WORLD_NAME, getSpawn(world) is called immediately after setupWorld() returns, and at that point the world may not yet be registered with Bukkit, causing the NPE.

@SirYwell

Copy link
Copy Markdown
Member

The issue occurs because BukkitSetupUtils.setupWorld() calls worldManager().handleWorldCreation(...) which may create the world asynchronously (e.g. via Multiverse or Paper world creation).

No, world creation is not asynchronous. Maybe your fork is at fault.

@bastigfz

Copy link
Copy Markdown
Author

No, world creation is not asynchronous. Maybe your fork is at fault.

You are right, Bukkit.createWorld() is synchronous. I was wrong about async world creation.

Looking at the stack trace from the reporter again:

[16:52:05] NPE at BukkitUtil.getSpawn()
[16:52:05] Creating world plotworld...
[16:52:06] World plotworld created!

The NPE happens before the world is even created. This means setupWorld() returned the world name without handleWorldCreation() having been called, or the world creation failed silently.

I cannot fully explain the root cause from the code alone – it could be a Leaf-specific behavior, a version mismatch in 7.5.13-Premium, or something else. However, the defensive null-checks in getSpawn() and BukkitPlayer.teleport() are still valid: they prevent the crash regardless of why the world is not registered, and they follow the same null-safe pattern already used in setSpawn().

@SirYwell

Copy link
Copy Markdown
Member

No, world creation is not asynchronous. Maybe your fork is at fault.

You are right, Bukkit.createWorld() is synchronous. I was wrong about async world creation.

Looking at the stack trace from the reporter again:

[16:52:05] NPE at BukkitUtil.getSpawn()
[16:52:05] Creating world plotworld...
[16:52:06] World plotworld created!

The NPE happens before the world is even created. This means setupWorld() returned the world name without handleWorldCreation() having been called, or the world creation failed silently.

I cannot fully explain the root cause from the code alone – it could be a Leaf-specific behavior, a version mismatch in 7.5.13-Premium, or something else. However, the defensive null-checks in getSpawn() and BukkitPlayer.teleport() are still valid: they prevent the crash regardless of why the world is not registered, and they follow the same null-safe pattern already used in setSpawn().

This really sounds like a problem with the server software you are using.

@NonSwag

NonSwag commented Jul 26, 2026

Copy link
Copy Markdown

#createWorld will only ever return null if another world with the exact same UUID already exists, everything else throws an exception.
If the world did not exist before (which is generally the case for the setup command) #createWorldwill never return null

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.

5 participants