Skip to content

OfflinePlayer#setWhitelisted writes an empty name to whitelist.json for players obtained via getOfflinePlayer(UUID) #14412

Open

Description

@foenichs

Expected behavior

Whitelisting a player with Bukkit.getOfflinePlayer(uuid).setWhitelisted(true) should store the player’s real name next to the UUID, using the profile cache or the player’s profile, like /whitelist add does.

Observed/Actual behavior

whitelist.json gets {"uuid": "<uuid>", "name": ""}. /whitelist list then shows a blank entry, and the player is missing from tab-completion of /whitelist remove.

Screenshot of /whitelist list

Steps/models to reproduce

  1. Call Bukkit.getOfflinePlayer(uuid).setWhitelisted(true) for a player who is not online. For example, call it during the configuration phase, in a handler for PlayerCustomClickEvent.
  2. Open whitelist.json: the name is "".
  3. Run /whitelist list: the entry shows as blank.

Plugin and Datapack List

Just a test plugin that triggers the behaviour described in the 'Steps to reproduce' section. There are no data packs (only vanilla).

Paper version

This server is running Paper version 26.3-205-main@a90108f (2026-10-17T20:50:27Z) (Implementing API version 26.3.build.205-stable)

Other

No response

Activity

  1. added theissue type on Oct 18, 2026
  2. MonoDev-1 commented on Oct 19, 2026

    @MonoDev-1
    @Override
        public OfflinePlayer getOfflinePlayer(UUID id) {
            Preconditions.checkArgument(id != null, "UUID id cannot be null");
    
            OfflinePlayer result = this.getPlayer(id);
            if (result == null) {
                result = this.offlinePlayers.get(id);
                if (result == null) {
                    result = new CraftOfflinePlayer(this, new NameAndId(id, ""));
                    this.offlinePlayers.put(id, result);
                }
            } else {
                this.offlinePlayers.remove(id);
            }
    
            return result;
        }

    I believe the bug comes from this line: result = new CraftOfflinePlayer(this, new NameAndId(id, "")); which gives the offline player an empty name and setting whitelisted to true forwards the NameAndId to UserWhiteListEntry and gets serialized with the empty name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Fields

    MC Issue

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions