/pay <name> <amount> sometimes lands in a player's personal account instead of the GOVERNMENT account of the same name — and it's non-deterministic ("sometimes").
DemocracyCraft operates several governments as Minecraft player alt-accounts whose username equals a Treasury GOVERNMENT account's display_name. Two names currently exist as both:
DCGovernmentAV → GOVERNMENT #49929 ($3.38M) and player alt PERSONAL #104237DCGovernmentOR → GOVERNMENT #27107 ($3.35M) and player alt PERSONAL #104236PayCommand.doPay (treasury commands/PayCommand.java:72-88) resolves the target player-first:
OfflinePlayer target = Bukkit.getOfflinePlayerIfCached(targetName); // ← only resolves if cached
boolean knownPlayer = target != null && (target.hasPlayedBefore() || target.isOnline());
if (knownPlayer) payPlayer(...); // → PERSONAL account
else getGovernmentAccountByName(targetName) → payGov; // → GOVERNMENT account (fallback)
Because a real player owns DCGovernmentOR, the payment goes to the personal account whenever the username is in the server usercache, and only falls through to the GOVERNMENT account when it isn't — hence the cache-dependent "sometimes". The existing code comment even acknowledges the ambiguity ("use /pay-account to disambiguate").
AccountResolver//pay-account <type> <name> and /gov, tax, and fines lookups all go through the type-filtered findGovernmentAccountByName and are not affected — only the bare-name /pay is.
#49929 received $140k and GOV #27107 received payments via /pay (the cache-miss case routed correctly).#104237 shows admin clean-up of misrouted funds: ledger memos "Admin transfer: Incorrectly given starting balance", "Admin transfer: Cleanup" (now $0) — i.e. staff have already had to manually fix mis-paid money here.Make /pay deterministic on a player↔GOVERNMENT name collision: if targetName matches both a known player AND a non-archived GOVERNMENT account, refuse and instruct the sender to use /pay-account government <name> or /pay-account player <name>. (Add a cheap AccountService.governmentAccountExists(name) check used alongside the player lookup.) Do not rely on getOfflinePlayerIfCached cache state to decide routing.
/pay DCGovernmentOR 100 with the player cached AND uncached both yield the same result (a disambiguation prompt, not a silent personal-account payment).Part of a set to fix government name-collisions once and for all (see sibling Realty + audit issues).