Comparator Contract Violation in GroupNode.NodeComparator.compare() from IntelliJ 2025.2+?

I’m working on upgrading the IntelliJ Elixir plugin to support 2025.2.1+, and have found a really weird bug that didn’t exist before, with regards to Usages.

java.lang.IllegalArgumentException: Comparison method violates its general contract! in UsageViewImpl.syncModelWithSwingNodes() due to how the comparator is implemented in GroupNode.NodeComparator.

It seems to happen with bulk usage operations, particularly in plugin tests.

What I understand..

(Current IntelliJ 2025.2.1 release, this has recently changed…):

platform/usageView-impl/src/com/intellij/usages/impl/GroupNode.java:305

// Line 305 in NodeComparator.compare() - IntelliJ 2025.2.1
return System.identityHashCode(u1) - System.identityHashCode(u2); // VIOLATION

Stack Trace

java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.base/java.util.TimSort.mergeHi(TimSort.java:903)
    at java.base/java.util.TimSort.mergeAt(TimSort.java:520)
    at java.base/java.util.TimSort.mergeForceCollapse(TimSort.java:461)
    at java.base/java.util.TimSort.sort(TimSort.java:254)
    at java.base/java.util.Arrays.sort(Arrays.java:1308)
    at java.base/java.util.Vector.sort(Vector.java:1385)
    at com.intellij.usages.impl.UsageViewImpl.syncModelWithSwingNodes(UsageViewImpl.java:589)
    at com.intellij.usages.impl.UsageViewImpl.fireEvents(UsageViewImpl.java:497)

How to reproduce

# Clone intellij-elixir plugin (feature/kotlin-220 branch)
git clone https://github.com/KronicDeth/intellij-elixir
cd intellij-elixir
git checkout feature/kotlin-220

# Run find usages tests - 11/22 fail with comparator violation
./gradlew test --tests "org.elixir_lang.FindUsagesTest"

Multiple tests fail with identical stack trace at UsageViewImpl.syncModelWithSwingNodes:589

Workarounds?

Not sure how to proceed from here, I’m considering just ignoring the test for now, and seeing how many users have issues?

1 Like

Hello. Thanks for reporting this.

What is this “feature/kotlin220” though? I can’t find this branch anywhere

Apologies, I’ve since merged that branch, as we’re upgrading to support 2025.1/2.

Job is here which shows this failure:

Current PR is Support 2025.2+ IDEs by joshuataylor · Pull Request #3711 · KronicDeth/intellij-elixir · GitHub

This job shows different errors from the Elixir PSI implementation where smart pointer can’t be restored immediately after its creation.

2025-08-08T14:37:38.5364888Z   Caused by: com.intellij.testFramework.TestLoggerFactory$TestLoggerAssertionError: Cannot restore UNMATCHED_UNQUALIFIED_NO_PARENTHESES_CALL of class org.elixir_lang.psi.impl.ElixirUnmatchedUnqualifiedNoParenthesesCallImpl from injected{type=Identikit(class='org.elixir_lang.psi.impl.ElixirUnmatchedUnqualifiedNoParenthesesCallImpl', elementType=UNMATCHED_UNQUALIFIED_NO_PARENTHESES_CALL, fileLanguage='Elixir'), range=SmartPsiFileRangePointerImpl{psi:range=(11810,11898),type=Identikit(class='com.intellij.psi.PsiElement', elementType=-1, fileLanguage='')}, host=psi:range=(11591,12989),type=Identikit(class='org.elixir_lang.psi.impl.ElixirLiteralSigilHeredocImpl', elementType=LITERAL_SIGIL_HEREDOC, fileLanguage='Elixir')}; restored=null in Project(name=ModuleNestedRecursiveDeclaration, containerState=COMPONENT_CREATED, componentStore=/tmp/unitTest_functionRecursiveUsage_310bFFksLSWs8g7ZQAjNtPoeuNo/light_temp_310bFNTYknSqqbpbXFU4rVtRSzr.ipr)
2025-08-08T14:37:38.5371725Z       at com.intellij.testFramework.TestLoggerFactory$TestLogger.error(TestLoggerFactory.java:457)
2025-08-08T14:37:38.5373253Z       at com.intellij.openapi.diagnostic.Logger.error(Logger.java:375)
2025-08-08T14:37:38.5379403Z       at com.intellij.psi.impl.smartPointers.SmartPsiElementPointerImpl.createElementInfo(SmartPsiElementPointerImpl.java:153)
2025-08-08T14:37:38.5381269Z       at com.intellij.psi.impl.smartPointers.SmartPsiElementPointerImpl.<init>(SmartPsiElementPointerImpl.java:48)