# GriefPrevention3D v18.2.10
**Wiki:** https://github.com/castledking/GriefPrevention3D/wiki
## Fixes
### `/abandonclaim` NullPointerException when any admin claim exists
**This is the real cause of the `/abandonclaim` crash.** The null guard added in
v18.2.9 was in `abandonClaimHandler` and was a genuine latent bug, but it was *not*
what players were hitting — the crash happens earlier in the call chain, and is
unrelated to the `AbandonReturnRatio` config value.
Full stack trace from a v18.2.9 server:
```
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.UUID.equals(Object)"
because the return value of "Claim.getOwnerID()" is null
at DataStore.cleanupAutoNeighborsOnDelete(DataStore.java:1434)
at DataStore.deleteClaimUnchecked(DataStore.java:948)
at DataStore.deleteClaimWithResult(DataStore.java:893)
at GriefPrevention.abandonClaimHandler(GriefPrevention.java:3609)
```
`cleanupAutoNeighborsOnDelete` runs on every claim deletion. It correctly null-checks
the *deleted* claim's owner, then scans every top-level claim in the datastore looking
for other claims owned by the same player:
```java
for (Claim otherClaim : this.claims) {
if (!otherClaim.inDataStore) continue;
if (otherClaim.parent != null) continue;
if (otherClaim.id.equals(deletedClaim.id)) continue;
if (!otherClaim.getOwnerID().equals(deletedOwner)) continue; // <-- NPE
```
**Administrative claims have a null `ownerID`.** As soon as that scan reached any admin
claim, it threw. The sibling method `autoGrantNeighborTrust` guards exactly this case
(`if (otherClaim.getOwnerID() == null) continue;`) — the guard was simply omitted in the
deletion path.
Conditions to trigger it (all common, which is why it looked like "nobody can abandon
claims"):
- `MinimumDistance` greater than `0` (otherwise auto-neighbor cleanup returns early),
- at least one administrative claim anywhere in the datastore,
- the abandoning player having at least one auto-neighbor entry — which happens
automatically between any two nearby claims owned by different players, so it is the
norm on a server with adjacent claims.
Because the exception is thrown *after* `deleteClaimUnchecked` has already removed the
claim from memory and from storage, the abandon itself partially succeeded — the player
got no success message, no claim blocks refunded message, and a console stack trace,
making it look like the command did nothing.
**Fix:** added the missing `otherClaim.getOwnerID() == null` guard, matching
`autoGrantNeighborTrust`. Admin claims can never match a specific deleted owner, so
skipping them is the correct behavior.
### Not caused by the migration or by `AbandonReturnRatio`
For the record, since this was initially suspected: auto-neighbor trust
(`cleanupAutoNeighborsOnDelete`, `autoGrantNeighborTrust`, `addAutoNeighbor`) is a
**GriefPrevention3D-only feature** — it does not exist anywhere in upstream
GriefPrevention. Upstream's `deleteClaim` path has no equivalent code and cannot throw
this exception, which is why the crash appeared only after migrating to GP3D. It is
triggered purely by having an admin claim plus `MinimumDistance > 0`; no migrated data,
storage backend (File or MySQL), or `AbandonReturnRatio` setting is involved.
## Known issue still under investigation
### `/acb` producing no output
Still unresolved. The command-map corruption fixed in v18.2.9 (dynamic standalone
registration permanently overwriting a `plugin.yml` command, so
`plugin.getCommand("acb")` returned `null` forever and the legacy handler silently
attached to nothing) is a real bug and remains fixed, but it has not been confirmed as
the cause here.
v18.2.9 added a console warning for that exact failure mode. To diagnose, run
`/gpdebug` and restart, then check startup output for:
```
Could not register legacy standalone command 'acb': plugin.getCommand(...) returned null.
```
- If that warning appears, the registration collision is the cause. Removing any
`standalone:` entry containing `acb` from the `blocks` subcommand in `alias.yml` will
resolve it, since it is redundant with the dedicated legacy `/acb` handler.
- If it does not appear, `/acb` is attached correctly and the failure is elsewhere —
the exact observed behavior (silence vs. usage text vs. permission denial) is needed
to narrow it down further.
## Files Changed
```
M gradle.properties
M pom.xml
M src/main/java/me/ryanhamshire/GriefPrevention/DataStore.java
```
Optional dependencies
PlaceholderAPI
Any compatible version
QuickShop-Hikari
Any compatible version
VaultUnlocked
Any compatible version
Developer information
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle.
maven { name = "Modrinth"; url = "https://api.modrinth.com/maven" }