Skip to content

fix: Intermittent Forgified Fabric API creative inventory crash on Forge 1.20.1 - #81

Open
arnabnandy7 wants to merge 2 commits into
Monad-Modding:moonlightlessfrom
arnabnandy7:fix/forgified-fabric-creative-crash
Open

fix: Intermittent Forgified Fabric API creative inventory crash on Forge 1.20.1#81
arnabnandy7 wants to merge 2 commits into
Monad-Modding:moonlightlessfrom
arnabnandy7:fix/forgified-fabric-creative-crash

Conversation

@arnabnandy7

Copy link
Copy Markdown
Contributor

Summary

Fixes an intermittent creative inventory crash when Clutter No More is used with Forgified Fabric API and Sinytra Connector on Minecraft 1.20.1 Forge.

Fixes #27

Root cause

Clutter No More extends ItemStack equality so generated shape items and their parent items compare as equivalent.

However, ItemStackLinkedSet.TYPE_AND_TAG continued calculating hashes from the original item. This violated the required equality/hash contract:

  • Shape and parent stacks compared equal.
  • The same stacks produced different hashes.

Forge uses this strategy in MutableHashedLinkedMap when building creative inventory tabs. Depending on the map layout, Forgified Fabric API's iterator-removal pass could remove an unexpected entry and throw:

java.util.ConcurrentModificationException
at net.minecraftforge.common.util.MutableHashedLinkedMap$1.remove
at net.fabricmc.fabric.impl.itemgroup.ItemGroupEventsImpl.onCreativeModeTabBuildContents

The inconsistent map layout explains why the crash occurred intermittently.

Solution

  • Normalize shape stacks to their parent before hashing.
  • Normalize related stacks before comparing their tags.
  • Preserve inequality when related stacks contain different NBT data.
  • Restrict the compatibility implementation to Forge 1.20.1.
  • Add a development-only before/after regression check.

Regression verification

The regression check recreates the previous broken hash strategy using actual registered item stacks.

Before

It verifies that shape and parent stacks compare equal while producing different hashes, then reproduces the reported:

ConcurrentModificationException

from MutableHashedLinkedMap.Iterator.remove().

After

It verifies that:

  • Equal shape and parent stacks produce equal normalized hashes.
  • Different NBT data remains unequal.
  • Forgified Fabric API's iterator-removal pattern completes successfully.
  • The map is empty after all entries are removed.

Successful runtime output:

[HashContractRegression] BEFORE reproduced: equal shape/parent stacks had different vanilla hashes; AFTER verified: normalized hashes match and FFAPI iterator removal completed

Validation

The development regression check was executed during a Forge 1.20.1 server launch.

The following builds pass:

./gradlew :1.20.1-forge:build
./gradlew :1.21.1-fabric:build
./gradlew :1.21.1-neoforge:build

Runtime verification:

./gradlew :1.20.1-forge:runServer

Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>
Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>
@arnabnandy7 arnabnandy7 changed the title `Fix intermittent Forgified Fabric API creative inventory crash on Forge 1.20.1 Fix intermittent Forgified Fabric API creative inventory crash on Forge 1.20.1 Sep 1, 2026
@arnabnandy7 arnabnandy7 changed the title Fix intermittent Forgified Fabric API creative inventory crash on Forge 1.20.1 fix: Intermittent Forgified Fabric API creative inventory crash on Forge 1.20.1 Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash with Forgified Fabric API still happens (1.20.1)

1 participant