Skip to content

Architectury Transformer crashes on NeoForge with StringIndexOutOfBoundsException Environment #28

Description

@Raguto

Architectury Transformer crashes on NeoForge with StringIndexOutOfBoundsException
Environment

Minecraft Version: 1.21.10
Architectury Loom: 1.11.458
Architectury Plugin: 3.4.162
Architectury Transformer Runtime: 5.2.87
NeoForge: 21.4.31-beta
Gradle: 9.1.0
JDK: 21.0.8
OS: Windows

Description
The Architectury runtime transformer crashes when launching a NeoForge client with StringIndexOutOfBoundsException during the removeDuplicates phase. The Fabric client runs without issues.
Stack Trace
[Architectury Transformer] Architectury Runtime 5.2.87
[Architectury Transformer] Read classpath in 2.345 s
[Architectury Transformer] Listening at C:\Users...\common\build\devlibs\pocket_villagers-1.0.0-1.21.10-dev.jar
java.lang.StringIndexOutOfBoundsException: Range [0, -1) out of bounds for length 70
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:55)
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:52)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:213)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:210)
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckFromToIndex(Preconditions.java:112)
at java.base/jdk.internal.util.Preconditions.checkFromToIndex(Preconditions.java:349)
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4865)
at java.base/java.lang.String.substring(String.java:2834)
at dev.architectury.transformer.TransformerRuntime.lambda$null$8(TransformerRuntime.java:250)
at dev.architectury.transformer.input.BaseFileAccess.handle(BaseFileAccess.java:56)
at dev.architectury.transformer.input.ForwardingFileView.handle(ForwardingFileView.java:42)
at dev.architectury.transformer.TransformerRuntime.lambda$removeDuplicates$9(TransformerRuntime.java:246)
at java.base/java.util.ArrayList.removeIf(ArrayList.java:1755)
at java.base/java.util.ArrayList.removeIf(ArrayList.java:1743)
at dev.architectury.transformer.TransformerRuntime.removeDuplicates(TransformerRuntime.java:240)
at dev.architectury.transformer.TransformerRuntime.main(TransformerRuntime.java:214)

Root Cause
The transformer fails when processing NeoForge's neoform dependency, which is a .zip file rather than a .jar:
C:\Users\Raguto.gradle\caches...\net.neoforged\neoform...\neoform-1.21.4-....zip
The code in TransformerRuntime.java:250 calls String.substring() with an index from lastIndexOf(), which returns -1 when the expected separator isn't found. The transformer assumes all classpath entries follow a specific format (presumably .jar files), and crashes when encountering the .zip artifact.

Why Fabric Works
Fabric doesn't include the neoform .zip dependency, so the transformer never encounters the problematic classpath entry. This is NeoForge-specific.

The transformer should either:
Handle .zip files gracefully without crashing
Skip non-.jar classpath entries
Add a defensive check for lastIndexOf() == -1 before calling substring()

Reproduction
Set up a standard Architectury multi-loader project for MC 1.21.10
Add NeoForge dependency: modImplementation "net.neoforged:neoforge:21.4.31-beta"
Run ./gradlew :neoforge:runClient
Observe crash in transformer

Additional Notes
This appears to be specific to MC 1.21.10 with NeoForge 21.4.x
The issue blocks all NeoForge development for Architectury projects on this version
Fabric builds and runs successfully with the same project structure

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions