The bug
This bug was introduced in 25w07a. Previously, resource packs could use a filter block in pack.mcmeta to remove all blockstate files. Now, this causes a resource reload fail unless at least one blockstate remains.
How to reproduce
Download the two resource packs
Equip the first one, which filters out every blockstate except zombie heads
Now equip the second one, which filters out every blockstate, period
Expected behavior
Both packs should work
Observed behavior
Second pack causes a resource reload fail with this stacktrace:
[22:46:02] [Render thread] [INFO] java.util.concurrent.CompletionException: java.lang.UnsupportedOperationException
at java.base/java.util.concurrent.CompletableFuture.wrapInCompletionException(CompletableFuture.java:323)
at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:359)
at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:364)
at java.base/java.util.concurrent.CompletableFuture.biApply(CompletableFuture.java:1334)
at java.base/java.util.concurrent.CompletableFuture$BiApply.tryFire(CompletableFuture.java:1301)
at java.base/java.util.concurrent.CompletableFuture$CoCompletion.tryFire(CompletableFuture.java:1240)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:531)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1794)
at net.minecraft.server.packs.resources.SimpleReloadInstance.lambda$prepareTasks$1(SimpleReloadInstance.java:51)
at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.compute(ForkJoinTask.java:1753)
at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.compute(ForkJoinTask.java:1745)
at java.base/java.util.concurrent.ForkJoinTask$InterruptibleTask.exec(ForkJoinTask.java:1662)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:511)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1450)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2019)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)
Caused by: java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:145)
at java.base/java.util.ImmutableCollections$AbstractImmutableMap.putIfAbsent(ImmutableCollections.java:1138)
at net.minecraft.client.resources.model.ModelManager.lambda$createBlockStateToModelDispatch$0(ModelManager.java:209)
at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:421)
at net.minecraft.client.resources.model.ModelManager.createBlockStateToModelDispatch(ModelManager.java:208)
at net.minecraft.client.resources.model.ModelManager.lambda$loadModels$1(ModelManager.java:197)
at java.base/java.util.concurrent.CompletableFuture.biApply(CompletableFuture.java:1332)
... 12 more
Code analysis
25w07a introduced ParallelMapTransform and changed ModelBakery to use it. When it’s given an input of size 0, it returns an empty map using Map.of(), which produces an immutable map. When ModelManager then tries to fill in the missing models with putIfAbsent, UnsupportedOperationException is thrown because the map is immutable.
If even a single blockstate definition remains present, a mutable map is returned and the code continues as expected.