cursive-ide/cursive

Frequent java.lang.IllegalStateException: Recursive update

Closed this issue · 4 comments

The last few weeks, me and my colleagues have started to see very frequent (sometimes several times a minute) exceptions from Cursive while typing into various .clj files. It seems to have started after a recent Cursive or IntelliJ update. I report these issues using the built-in Exception report function whenever they occur, but I wanted to also create an issue here in case I could help diagnose the issue somehow.

Cursive version: 1.14.0-eap1-2024.2
IntelliJ version: 2024.2.3 (Ultimate Edition) Build #IU-242.23339.11
macOS version: 15.0.1 (24A348)

The During querying provider part is sometimes present, sometimes not.

Please let me know if I can help diagnose this issue in any way!

During querying provider cursive.editor.ClojureLineMarkerProvider@22e78375 (class cursive.editor.ClojureLineMarkerProvider)

java.lang.IllegalStateException: Recursive update
	at java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1991)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2686)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2669)
	at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:112)
	at com.github.benmanes.caffeine.cache.LocalLoadingCache.get(LocalLoadingCache.java:58)
	at cursive.psi.impl.javaView.ClojureClassCreator.createClass(ClojureClassCreator.java:35)
	at cursive.intellij.class$classes_by_fqn$reify__7701$fn__7702.invoke(class.clj:279)
	at clojure.core$mapv$fn__8561.invoke(core.clj:7059)
	at clojure.lang.ArrayChunk.reduce(ArrayChunk.java:60)
	at clojure.core.protocols$fn__8266.invokeStatic(protocols.clj:135)
	at clojure.core.protocols$fn__8266.invoke(protocols.clj:123)
	at clojure.core.protocols$fn__8225$G__8220__8234.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:31)
	at clojure.core.protocols$fn__8258.invokeStatic(protocols.clj:74)
	at clojure.core.protocols$fn__8258.invoke(protocols.clj:74)
	at clojure.core.protocols$fn__8199$G__8194__8212.invoke(protocols.clj:13)
	at clojure.core$reduce.invokeStatic(core.clj:6965)
	at clojure.core$mapv.invokeStatic(core.clj:7050)
	at clojure.core$mapv.invoke(core.clj:7050)
	at cursive.intellij.class$classes_by_fqn$reify__7701.compute(class.clj:279)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.runReadAction$lambda$3(AnyThreadWriteThreadingSupport.kt:219)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.runReadAction(AnyThreadWriteThreadingSupport.kt:228)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.runReadAction(AnyThreadWriteThreadingSupport.kt:219)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:852)
	at cursive.intellij.class$classes_by_fqn.invokeStatic(class.clj:278)
	at cursive.intellij.class$classes_by_fqn.invoke(class.clj:276)
	at clojure.lang.Var.invoke(Var.java:395)
	at cursive.api.DelayedFn.invoke(DelayedFn.java:41)
	at cursive.psi.impl.javaView.ClojureClassFinder.findClasses(ClojureClassFinder.java:40)
	at cursive.psi.impl.javaView.ClojureClassFinder.findClass(ClojureClassFinder.java:32)
	at com.intellij.psi.impl.JavaPsiFacadeImpl.doFindClass(JavaPsiFacadeImpl.java:106)
	at com.intellij.psi.impl.JavaPsiFacadeImpl.findClass(JavaPsiFacadeImpl.java:85)
	at cursive.indexes.java$find_class.invokeStatic(java.clj:25)
	at cursive.indexes.java$find_class.invoke(java.clj:22)
	at cursive.intellij.class$class_from_type$fn__7572.invoke(class.clj:52)
	at clojure.core$some.invokeStatic(core.clj:2718)
	at clojure.core$some.invoke(core.clj:2709)
	at cursive.intellij.class$class_from_type.invokeStatic(class.clj:52)
	at cursive.intellij.class$class_from_type.invoke(class.clj:36)
	at cursive.intellij.class$create_class$fn__7645.invoke(class.clj:160)
	at clojure.core$map$fn__5952.invoke(core.clj:2770)
	at clojure.lang.LazySeq.force(LazySeq.java:50)
	at clojure.lang.LazySeq.realize(LazySeq.java:89)
	at clojure.lang.LazySeq.seq(LazySeq.java:106)
	at clojure.lang.RT.seq(RT.java:612)
	at clojure.core$seq__5484.invokeStatic(core.clj:139)
	at clojure.core$concat$fn__5575.invoke(core.clj:727)
	at clojure.lang.LazySeq.force(LazySeq.java:50)
	at clojure.lang.LazySeq.realize(LazySeq.java:89)
	at clojure.lang.LazySeq.seq(LazySeq.java:106)
	at clojure.lang.RT.seq(RT.java:612)
	at clojure.core$seq__5484.invokeStatic(core.clj:139)
	at clojure.core$filter$fn__5979.invoke(core.clj:2826)
	at clojure.lang.LazySeq.force(LazySeq.java:50)
	at clojure.lang.LazySeq.realize(LazySeq.java:89)
	at clojure.lang.LazySeq.seq(LazySeq.java:106)
	at clojure.lang.RT.seq(RT.java:612)
	at clojure.core$seq__5484.invokeStatic(core.clj:139)
	at clojure.core$filter$fn__5979.invoke(core.clj:2826)
	at clojure.lang.LazySeq.force(LazySeq.java:50)
	at clojure.lang.LazySeq.realize(LazySeq.java:89)
	at clojure.lang.LazySeq.seq(LazySeq.java:106)
	at clojure.lang.LazySeq.first(LazySeq.java:118)
	at clojure.lang.RT.first(RT.java:769)
	at clojure.core$first__5466.invokeStatic(core.clj:55)
	at clojure.core$first__5466.invoke(core.clj:55)
	at cursive.intellij.class$create_class.invokeStatic(class.clj:164)
	at cursive.intellij.class$create_class.invoke(class.clj:101)
	at clojure.lang.Var.invoke(Var.java:390)
	at cursive.api.DelayedFn.invoke(DelayedFn.java:36)
	at cursive.psi.impl.javaView.ClojureClassCreator.lambda$new$0(ClojureClassCreator.java:26)
	at com.github.benmanes.caffeine.cache.LocalLoadingCache.lambda$newMappingFunction$3(LocalLoadingCache.java:183)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent$14(BoundedLocalCache.java:2688)
	at java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1916)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2686)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2669)
	at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:112)
	at com.github.benmanes.caffeine.cache.LocalLoadingCache.get(LocalLoadingCache.java:58)
	at cursive.psi.impl.javaView.ClojureClassCreator.createClass(ClojureClassCreator.java:35)
	at cursive.intellij.class$class_by_text_offset.invokeStatic(class.clj:284)
	at cursive.intellij.class$class_by_text_offset.invoke(class.clj:281)
	at cursive.extensions.clojure.core.protocols$deftype_locals.invokeStatic(protocols.clj:380)
	at cursive.extensions.clojure.core.protocols$deftype_locals.invoke(protocols.clj:365)
	at cursive.extensions.clojure.core.resolve$locals.invokeStatic(resolve.clj:88)
	at cursive.extensions.clojure.core.resolve$locals.invoke(resolve.clj:85)
	at cursive.extensions.clojure.core.protocols$fn__12219.invokeStatic(protocols.clj:577)
	at cursive.extensions.clojure.core.protocols$fn__12219.invoke(protocols.clj:577)
	at cursive.resolve$fn__3535$fn__3536$fn__3539.invoke(resolve.clj:254)
	at clojure.core$map$fn__5952.invoke(core.clj:2772)
	at clojure.lang.LazySeq.force(LazySeq.java:50)
	at clojure.lang.LazySeq.realize(LazySeq.java:89)
	at clojure.lang.LazySeq.seq(LazySeq.java:106)
	at clojure.lang.Cons.next(Cons.java:41)
	at clojure.lang.RT.boundedLength(RT.java:1867)
	at clojure.lang.RestFn.applyTo(RestFn.java:133)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:662)
	at cursive.resolve$fn__3535$fn__3536.invoke(resolve.clj:250)
	at cursive.psi$cached_value$reify__889.compute(psi.clj:564)
	at com.intellij.psi.impl.PsiCachedValueImpl$Direct.doCompute(PsiCachedValueImpl.kt:77)
	at com.intellij.util.CachedValueBase.lambda$getValueWithLock$3(CachedValueBase.java:236)
	at com.intellij.util.CachedValueBase.computeData(CachedValueBase.java:43)
	at com.intellij.util.CachedValueBase.lambda$getValueWithLock$4(CachedValueBase.java:236)
	at com.intellij.openapi.util.RecursionManager$1.computePreventingRecursion(RecursionManager.java:111)
	at com.intellij.openapi.util.RecursionGuard.doPreventingRecursion(RecursionGuard.java:27)
	at com.intellij.openapi.util.RecursionManager.doPreventingRecursion(RecursionManager.java:66)
	at com.intellij.util.CachedValueBase.getValueWithLock(CachedValueBase.java:237)
	at com.intellij.psi.impl.PsiCachedValueImpl$Direct.getValue(PsiCachedValueImpl.kt:81)
	at com.intellij.util.CachedValuesManagerImpl.getCachedValue(CachedValuesManagerImpl.java:83)
	at cursive.psi$cached_value.invokeStatic(psi.clj:567)
	at cursive.psi$cached_value.doInvoke(psi.clj:555)
	at clojure.lang.RestFn.invoke(RestFn.java:532)
	at cursive.resolve$list_resolve_symbols.invokeStatic(resolve.clj:260)
	at cursive.resolve$list_resolve_symbols.invoke(resolve.clj:259)
	at cursive.intellij.gutter$line_marker_info$fn__16548$fn__16556.invoke(gutter.clj:54)
	at cursive.intellij.gutter$line_marker_info$fn__16548.invoke(gutter.clj:53)
	at clojure.core$some.invokeStatic(core.clj:2718)
	at clojure.core$some.invoke(core.clj:2709)
	at cursive.intellij.gutter$line_marker_info.invokeStatic(gutter.clj:47)
	at cursive.intellij.gutter$line_marker_info.invoke(gutter.clj:43)
	at clojure.lang.Var.invoke(Var.java:386)
	at cursive.api.DelayedFn.invoke(DelayedFn.java:31)
	at cursive.editor.ClojureLineMarkerProvider.getLineMarkerInfo(Gutter.kt:14)
	at com.intellij.codeInsight.daemon.impl.LineMarkersPass.queryProviders(LineMarkersPass.java:180)
	at com.intellij.codeInsight.daemon.impl.LineMarkersPass.lambda$doCollectMarkers$2(LineMarkersPass.java:108)
	at com.intellij.codeInsight.daemon.impl.Divider.divideInsideAndOutsideInOneRoot(Divider.java:97)
	at com.intellij.codeInsight.daemon.impl.LineMarkersPass.doCollectMarkers(LineMarkersPass.java:104)
	at com.intellij.codeInsight.daemon.impl.LineMarkersPass.doCollectInformation(LineMarkersPass.java:77)
	at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:67)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$2(PassExecutorService.java:431)
	at com.intellij.platform.diagnostic.telemetry.helpers.TraceKt.runWithSpanIgnoreThrows(trace.kt:118)
	at com.intellij.platform.diagnostic.telemetry.helpers.TraceUtil.runWithSpanThrows(TraceUtil.java:36)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$3(PassExecutorService.java:426)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.tryRunReadAction(AnyThreadWriteThreadingSupport.kt:291)
	at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:965)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$4(PassExecutorService.java:417)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$13(CoreProgressManager.java:660)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:735)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:691)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:659)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:79)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.doRun(PassExecutorService.java:416)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$run$0(PassExecutorService.java:392)
	at com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl.cacheFileTypesInside(FileTypeManagerImpl.java:802)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$run$1(PassExecutorService.java:392)
	at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport.executeByImpatientReader(AnyThreadWriteThreadingSupport.kt:486)
	at com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:178)
	at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:390)
	at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:259)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1491)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:2073)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2035)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)

Really annoying since it breaks code browsing & usage tracking for certain functions.

In my experience it happens consistently when the caret is anywhere in between a defrecord statement, protocol implementations for the defrecord also loses go-to-definition capability

Setup:
Cursive: 1.14.0-eap1-2024.2
IntelliJ IDEA Community Edition 2024.2.4 (242.23726.103)

Sorry, I know this one has been annoying. It's fixed for the next EAP, but the change wasn't correctly tagged in git so this issue wasn't marked as resolved.

Fix released in 1.14.0-eap2 on 2024-11-08.