Repository: FabricMC/fabric (Java)

Issue:
Error when executing data pack function using FAPI in 1.21.6 pre-3
```
[14:56:15] [Server thread/WARN]: Failed to execute function pandamium:startup/place_dummy_blocks
java.lang.IllegalStateException: LootTable appears to be unregistered, but has been asked to generate loot
	at knot/net.fabricmc.fabric.impl.loot.LootUtil.lambda$getEntry$2(LootUtil.java:71) ~[fabric-loot-api-v3-1.1.0+9889468542-dbce32c098484123.jar:?]
	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[?:?]
	at knot/net.fabricmc.fabric.impl.loot.LootUtil.getEntry(LootUtil.java:70) ~[fabric-loot-api-v3-1.1.0+9889468542-dbce32c098484123.jar:?]
	at knot/net.minecraft.class_52.wrapMethod$zem000$fabric-loot-api-v3$fabric$modifyDrops(class_52.java:1050) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_52.method_328(class_52.java) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_52.method_320(class_52.java:115) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_52.method_319(class_52.java:132) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_52.method_51878(class_52.java:127) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_3039.method_13180(class_3039.java:433) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_3039.method_13197(class_3039.java:416) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_3039.method_13177(class_3039.java:97) ~[server-intermediary.jar:?]
	at knot/com.mojang.brigadier.context.ContextChain.runExecutable(ContextChain.java:73) ~[brigadier-1.3.10.jar:?]
	at knot/net.minecraft.class_8865.method_54416(class_8865.java:29) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_8865.execute(class_8865.java:13) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_8856.method_54405(class_8856.java:8) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_8847.method_54388(class_8847.java:8) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_8854.method_54390(class_8854.java:107) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_2170.method_54313(class_2170.java:420) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_2991.method_12904(class_2991.java:70) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_231.method_17938(class_231.java:17) ~[server-intermediary.jar:?]
	at java.base/java.util.Optional.ifPresent(Optional.java:178) ~[?:?]
	at knot/net.minecraft.class_231.method_967(class_231.java:17) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_231.method_974(class_231.java:9) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_236.method_988(class_236.java:84) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_3218.method_29203(class_3218.java:433) ~[server-intermediary.jar:?]
	at knot/net.minecraft.class_3218.method_18765(class_3218.java:338) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.method_3813(MinecraftServer.java:1063) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.method_3748(MinecraftServer.java:947) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.method_29741(MinecraftServer.java:707) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:291) ~[server-intermediary.jar:?]
	at java.base/java.lang.Thread.run(Thread.java:1575) [?:?]
```


Discussion: Thank you 👍
```
[14:56:15] [Server thread/WARN]: Failed to execute function pandamium:startup/place_dummy_blocks
java.lang.IllegalStateException: LootTable appears to be unregistered, but has been asked to generate loot
	at knot/net.fabricmc.fabric.impl.loot.LootUtil.lambda$getEntry$2(LootUtil.java:71) ~[fabric-loot-api-v3-1.1.0+9889468542-dbce32c098484123.jar:?]
	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[?:?]
	at knot/net.fabricmc.fabric.impl.loot.LootUtil.getEntry(LootUtil.java:70) ~[fabric-loot-api-v3-1.1.0+9889468542-dbce32c098484123.jar:?]
	at knot/net.minecraft.loot.LootTable.wrapMethod$zem000$fabric-loot-api-v3$fabric$modifyDrops(LootTable.java:1050) ~[server-intermediary.jar:?]
	at knot/net.minecraft.loot.LootTable.generateUnprocessedLoot(LootTable.java) ~[server-intermediary.jar:?]
	at knot/net.minecraft.loot.LootTable.generateLoot(LootTable.java:115) ~[server-intermediary.jar:?]
	at knot/net.minecraft.loot.LootTable.generateLoot(LootTable.java:132) ~[server-intermediary.jar:?]
	at knot/net.minecraft.loot.LootTable.generateLoot(LootTable.java:127) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.command.LootCommand.getFeedbackMessageSingle(LootCommand.java:433) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.command.LootCommand.executeLoot(LootCommand.java:416) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.command.LootCommand.method_13177(LootCommand.java:97) ~[server-intermediary.jar:?]
	at knot/com.mojang.brigadier.context.ContextChain.runExecutable(ContextChain.java:73) ~[brigadier-1.3.10.jar:?]
	at knot/net.minecraft.command.FixedCommandAction.execute(FixedCommandAction.java:29) ~[server-intermediary.jar:?]
	at knot/net.minecraft.command.FixedCommandAction.execute(FixedCommandAction.java:13) ~[server-intermediary.jar:?]
	at knot/net.minecraft.command.SourcedCommandAction.method_54405(SourcedCommandAction.java:8) ~[server-intermediary.jar:?]
	at knot/net.minecraft.command.CommandQueueEntry.execute(CommandQueueEntry.java:8) ~[server-intermediary.jar:?]
	at knot/net.minecraft.command.CommandExecutionContext.run(CommandExecutionContext.java:107) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.command.CommandManager.callWithContext(CommandManager.java:420) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.function.CommandFunctionManager.execute(CommandFunctionManager.java:70) ~[server-intermediary.jar:?]
	at knot/net.minecraft.world.timer.FunctionTimerCallback.method_17938(FunctionTimerCallback.java:17) ~[server-intermediary.jar:?]
	at java.base/java.util.Optional.ifPresent(Optional.java:178) ~[?:?]
	at knot/net.minecraft.world.timer.FunctionTimerCallback.call(FunctionTimerCallback.java:17) ~[server-intermediary.jar:?]
	at knot/net.minecraft.world.timer.FunctionTimerCallback.call(FunctionTimerCallback.java:9) ~[server-intermediary.jar:?]
	at knot/net.minecraft.world.timer.Timer.processEvents(Timer.java:84) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.world.ServerWorld.tickTime(ServerWorld.java:433) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.world.ServerWorld.tick(ServerWorld.java:338) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.tickWorlds(MinecraftServer.java:1063) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:947) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:707) ~[server-intermediary.jar:?]
	at knot/net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:291) ~[server-intermediary.jar:?]
	at java.base/java.lang.Thread.run(Thread.java:1575) [?:?]
```



Fix (patch):
diff --git a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/api/loot/v3/LootTableEvents.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/api/loot/v3/LootTableEvents.java
index 8a13e9d4f2..047337140c 100644
--- a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/api/loot/v3/LootTableEvents.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/api/loot/v3/LootTableEvents.java
@@ -106,9 +106,9 @@ private LootTableEvents() {
 	 * and don't wish to add a custom loot function to every table.
 	 * <br/>Note: if the table was requested to separate drops into stacks of a given size, the resulting drops from this event will be separated.
 	 */
-	public static final Event<ModifyDrops> MODIFY_DROPS = EventFactory.createArrayBacked(ModifyDrops.class, listeners -> (key, context, drops) -> {
+	public static final Event<ModifyDrops> MODIFY_DROPS = EventFactory.createArrayBacked(ModifyDrops.class, listeners -> (entry, context, drops) -> {
 		for (ModifyDrops listener : listeners) {
-			listener.modifyLootTableDrops(key, context, drops);
+			listener.modifyLootTableDrops(entry, context, drops);
 		}
 	});
 
@@ -155,10 +155,10 @@ public interface Loaded {
 	public interface ModifyDrops {
 		/**
 		 * Called after a loot table is finished generating drops to modify drops.
-		 * @param entry the loot table's registry entry
+		 * @param entry the loot table's registry entry. This will be a {@link RegistryEntry.Reference} if the lootTable is registered, or a {@link RegistryEntry.Direct} if the table is inline
 		 * @param context the loot context for the current drops
 		 * @param drops the list of drops from the loot table to modify
 		 */
-		void modifyLootTableDrops(RegistryEntry.Reference<LootTable> entry, LootContext context, List<ItemStack> drops);
+		void modifyLootTableDrops(RegistryEntry<LootTable> entry, LootContext context, List<ItemStack> drops);
 	}
 }
diff --git a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/FabricLootTable.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/FabricLootTable.java
index 082e03e181..cff8fc7ece 100644
--- a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/FabricLootTable.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/FabricLootTable.java
@@ -20,5 +20,5 @@
 import net.minecraft.registry.entry.RegistryEntry;
 
 public interface FabricLootTable {
-	void fabric$setRegistryEntry(RegistryEntry.Reference<LootTable> key);
+	void fabric$setRegistryEntry(RegistryEntry<LootTable> key);
 }
diff --git a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
index 20b10bf23b..41b1dee6b3 100644
--- a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
@@ -18,6 +18,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Function;
 
 import net.minecraft.loot.LootTable;
 import net.minecraft.registry.RegistryKeys;
@@ -53,7 +54,7 @@ public static LootTableSource determineSource(Resource resource) {
 		return LootTableSource.DATA_PACK;
 	}
 
-	public static RegistryEntry.Reference<LootTable> getEntry(ServerWorld world, LootTable table) {
+	public static RegistryEntry<LootTable> getEntryOrDirect(ServerWorld world, LootTable table) {
 		RegistryWrapper.WrapperLookup wrapperLookup = world
 				.getServer()
 				.getReloadableRegistries()
@@ -67,8 +68,7 @@ public static RegistryEntry.Reference<LootTable> getEntry(ServerWorld world, Loo
 				.streamEntries()
 				.filter(it -> it.value().equals(table))
 				.findFirst()
-				.orElseThrow(
-						() -> new IllegalStateException("LootTable appears to be unregistered, but has been asked to generate loot")
-				);
+				.map(Function.<RegistryEntry<LootTable>>identity())
+				.orElseGet(() -> RegistryEntry.of(table));
 	}
 }
diff --git a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableMixin.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableMixin.java
index 0e39fd796a..abf2ff06cc 100644
--- a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableMixin.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableMixin.java
@@ -42,12 +42,12 @@ class LootTableMixin implements FabricLootTable {
 	 */
 	@Unique
 	@Nullable
-	RegistryEntry.Reference<LootTable> entry = null;
+	RegistryEntry<LootTable> entry = null;
 
 	@WrapMethod(method = "generateUnprocessedLoot(Lnet/minecraft/loot/context/LootContext;Ljava/util/function/Consumer;)V")
 	private void fabric$modifyDrops(LootContext context, Consumer<ItemStack> lootConsumer, Operation<Void> original) {
 		if (entry == null) {
-			this.entry = LootUtil.getEntry(context.getWorld(), (LootTable) (Object) this);
+			this.entry = LootUtil.getEntryOrDirect(context.getWorld(), (LootTable) (Object) this);
 		}
 
 		List<ItemStack> list = new ObjectArrayList<>();
@@ -61,7 +61,7 @@ class LootTableMixin implements FabricLootTable {
 	}
 
 	@Override
-	public void fabric$setRegistryEntry(RegistryEntry.Reference<LootTable> key) {
+	public void fabric$setRegistryEntry(RegistryEntry<LootTable> key) {
 		this.entry = key;
 	}
 }