mojira.dev
MC-311679

Players can complete trades without payment if the villager restocks while the trading screen is open

Survival reproduction

  1. Unlock a fresh villager offer with max_uses: 3, such as a master toolsmith’s enchanted diamond pickaxe.

  2. Buy it exactly twice before its next available restock.

  3. Insert exactly the currently displayed emerald price so the third output appears.

  4. Keep the trading screen open while the villager reaches its workstation and restocks.

  5. The displayed price rises. Click the still-present output.

  6. You receive the enchanted diamond item, but none of the emeralds are consumed.

Expected: The output should disappear when the updated price exceeds the inserted payment.

Root cause

The server’s restock() changes demand and sends new offers, but never refreshes the cached MerchantContainer.

// net/minecraft/world/entity/npc/villager/Villager.java

public void restock() {
  this.updateDemand();

  for (MerchantOffer offer : this.getOffers()) {
    offer.resetUses();
  }

  this.resendOffersToTradingPlayer();
  this.lastRestockGameTime = this.level().getGameTime();
  this.numberOfRestocksToday++;
}

The stale result is removed before MerchantResultSlot.onTake() can validate payment.

// net/minecraft/world/inventory/MerchantResultSlot.java

@Override
public void onTake(final Player player, final ItemStack carried) {
  this.checkTakeAchievements(carried);
  MerchantOffer offer = this.slots.getActiveOffer();
  if (offer != null) {
    ItemStack buyA = this.slots.getItem(0);
    ItemStack buyB = this.slots.getItem(1);
    if (offer.take(buyA, buyB) || offer.take(buyB, buyA)) {
      this.merchant.notifyTrade(offer);
      player.awardStat(Stats.TRADED_WITH_VILLAGER);
      this.slots.setItem(0, buyA);
      this.slots.setItem(1, buyB);
    }

    this.merchant.overrideXp(this.merchant.getVillagerXp() + offer.getXp());
  }
}

POC

https://youtu.be/0CxUnFLySnU

Linked issues

Attachments

Comments 1

pxrune

etanaratsastaja

Community Consensus

Platform HC

Important

Trading

26.3 Pre-Release 2

26.3 Pre-Release 3

Retrieved