diff --git a/patches/api/create-TileStateInventoryHolder.patch b/patches/api/create-TileStateInventoryHolder.patch
new file mode 100644
index 0000000000..451c5caad6
--- /dev/null
+++ b/patches/api/create-TileStateInventoryHolder.patch
@@ -0,0 +1,226 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <jake.m.potrebic@gmail.com>
+Date: Fri, 20 Sep 2024 21:40:23 -0700
+Subject: [PATCH] create TileStateInventoryHolder
+
+a missing interface to centralize getSnapshotInventory methods
+
+diff --git a/src/main/java/io/papermc/paper/block/TileStateInventoryHolder.java b/src/main/java/io/papermc/paper/block/TileStateInventoryHolder.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/block/TileStateInventoryHolder.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.block;
++
++import org.bukkit.block.TileState;
++import org.bukkit.inventory.BlockInventoryHolder;
++import org.bukkit.inventory.Inventory;
++import org.checkerframework.checker.nullness.qual.NonNull;
++
++/**
++ * Represents a {@link TileState} block that has an inventory.
++ */
++public interface TileStateInventoryHolder extends TileState, BlockInventoryHolder {
++
++    /**
++     * Gets the inventory of the block represented by this block state.
++     * <p>
++     * If the block was changed to a different type in the meantime, the
++     * returned inventory might no longer be valid.
++     * <p>
++     * If this block state is not placed this will return the captured inventory
++     * snapshot instead.
++     *
++     * @return the inventory
++     */
++    @Override
++    @NonNull Inventory getInventory();
++
++    /**
++     * Gets the captured inventory snapshot of this container.
++     * <p>
++     * The returned inventory is not linked to any block. Any modifications to
++     * the returned inventory will not be applied to the block represented by
++     * this block state up until {@link #update(boolean, boolean)} has been
++     * called.
++     *
++     * @return the captured inventory snapshot
++     */
++    @NonNull Inventory getSnapshotInventory();
++}
+diff --git a/src/main/java/org/bukkit/block/ChiseledBookshelf.java b/src/main/java/org/bukkit/block/ChiseledBookshelf.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/block/ChiseledBookshelf.java
++++ b/src/main/java/org/bukkit/block/ChiseledBookshelf.java
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
+ /**
+  * Represents a captured state of a chiseled bookshelf.
+  */
+-public interface ChiseledBookshelf extends TileState, BlockInventoryHolder {
++public interface ChiseledBookshelf extends io.papermc.paper.block.TileStateInventoryHolder { // Paper - TileStateInventoryHolder
+ 
+     /**
+      * Gets the last interacted inventory slot.
+@@ -0,0 +0,0 @@ public interface ChiseledBookshelf extends TileState, BlockInventoryHolder {
+      */
+     void setLastInteractedSlot(int lastInteractedSlot);
+ 
+-    /**
+-     * @return inventory
+-     * @see Container#getInventory()
+-     */
++    // Paper - move docs to TileStateInventoryHolder
+     @NotNull
+     @Override
+     ChiseledBookshelfInventory getInventory();
+ 
+-    /**
+-     * @return snapshot inventory
+-     * @see Container#getSnapshotInventory()
+-     */
++    @Override // Paper - move docs to TileStateInventoryHolder
+     @NotNull
+     ChiseledBookshelfInventory getSnapshotInventory();
+ 
+diff --git a/src/main/java/org/bukkit/block/Container.java b/src/main/java/org/bukkit/block/Container.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/block/Container.java
++++ b/src/main/java/org/bukkit/block/Container.java
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
+ /**
+  * Represents a captured state of a container block.
+  */
+-public interface Container extends io.papermc.paper.block.LockableTileState, BlockInventoryHolder { // Paper
++public interface Container extends io.papermc.paper.block.LockableTileState, io.papermc.paper.block.TileStateInventoryHolder { // Paper
+ 
+-    /**
+-     * Gets the inventory of the block represented by this block state.
+-     * <p>
+-     * If the block was changed to a different type in the meantime, the
+-     * returned inventory might no longer be valid.
+-     * <p>
+-     * If this block state is not placed this will return the captured inventory
+-     * snapshot instead.
+-     *
+-     * @return the inventory
+-     */
+-    @NotNull
+-    @Override
+-    Inventory getInventory();
+-
+-    /**
+-     * Gets the captured inventory snapshot of this container.
+-     * <p>
+-     * The returned inventory is not linked to any block. Any modifications to
+-     * the returned inventory will not be applied to the block represented by
+-     * this block state up until {@link #update(boolean, boolean)} has been
+-     * called.
+-     *
+-     * @return the captured inventory snapshot
+-     */
+-    @NotNull
+-    Inventory getSnapshotInventory();
++    // Paper - moved to TileStateInventoryHolder
+ }
+diff --git a/src/main/java/org/bukkit/block/DecoratedPot.java b/src/main/java/org/bukkit/block/DecoratedPot.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/block/DecoratedPot.java
++++ b/src/main/java/org/bukkit/block/DecoratedPot.java
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.Nullable;
+ /**
+  * Represents a captured state of a decorated pot.
+  */
+-public interface DecoratedPot extends TileState, BlockInventoryHolder , org.bukkit.loot.Lootable { // Paper - expose loot table
++public interface DecoratedPot extends io.papermc.paper.block.TileStateInventoryHolder, org.bukkit.loot.Lootable { // Paper - expose loot table & TileStateInventoryHolder
+ 
+     /**
+      * Set the sherd on the provided side.
+@@ -0,0 +0,0 @@ public interface DecoratedPot extends TileState, BlockInventoryHolder , org.bukk
+     @NotNull
+     public List<Material> getShards();
+ 
+-    /**
+-     * @return inventory
+-     * @see Container#getInventory()
+-     */
++    // Paper - move docs to TileStateInventoryHolder
+     @NotNull
+     @Override
+     public DecoratedPotInventory getInventory();
+ 
+-    /**
+-     * @return snapshot inventory
+-     * @see Container#getSnapshotInventory()
+-     */
++    @Override // Paper - move docs to TileStateInventoryHolder
+     @NotNull
+     public DecoratedPotInventory getSnapshotInventory();
+ 
+diff --git a/src/main/java/org/bukkit/block/Jukebox.java b/src/main/java/org/bukkit/block/Jukebox.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/block/Jukebox.java
++++ b/src/main/java/org/bukkit/block/Jukebox.java
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.Nullable;
+ /**
+  * Represents a captured state of a jukebox.
+  */
+-public interface Jukebox extends TileState, BlockInventoryHolder {
++public interface Jukebox extends io.papermc.paper.block.TileStateInventoryHolder { // Paper - TileStateInventoryHolder
+ 
+     /**
+      * Gets the record inserted into the jukebox.
+@@ -0,0 +0,0 @@ public interface Jukebox extends TileState, BlockInventoryHolder {
+      */
+     public boolean eject();
+ 
+-    /**
+-     * @return inventory
+-     * @see Container#getInventory()
+-     */
++    // Paper - move docs to TileStateInventoryHolder
+     @NotNull
+     @Override
+     JukeboxInventory getInventory();
+ 
+-    /**
+-     * @return snapshot inventory
+-     * @see Container#getSnapshotInventory()
+-     */
++    @Override // Paper - move docs to TileStateInventoryHolder
+     @NotNull
+     JukeboxInventory getSnapshotInventory();
+ }
+diff --git a/src/main/java/org/bukkit/block/Lectern.java b/src/main/java/org/bukkit/block/Lectern.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/block/Lectern.java
++++ b/src/main/java/org/bukkit/block/Lectern.java
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
+ /**
+  * Represents a captured state of a lectern.
+  */
+-public interface Lectern extends TileState, BlockInventoryHolder {
++public interface Lectern extends io.papermc.paper.block.TileStateInventoryHolder { // Paper - TileStateInventoryHolder
+ 
+     /**
+      * Get the current lectern page.
+@@ -0,0 +0,0 @@ public interface Lectern extends TileState, BlockInventoryHolder {
+      */
+     void setPage(int page);
+ 
+-    /**
+-     * @return inventory
+-     * @see Container#getInventory()
+-     */
+-    @NotNull
+-    @Override
+-    Inventory getInventory();
+-
+-    /**
+-     * @return snapshot inventory
+-     * @see Container#getSnapshotInventory()
+-     */
+-    @NotNull
+-    Inventory getSnapshotInventory();
++    // Paper - moved to TileStateInventoryHolder
+ }