# Blog post: UI Freezes and the Dangers of Non-Cancellable Read Actions in Background Threads

**URL:** <https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895>\
**Category:** Announcements\
**Tags:** blog\
**Created:** [March 17, 2026, 8:18pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895 "2026-03-17T20:18:11Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [March 17, 2026, 8:18pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/1 "2026-03-17T20:18:11Z")

</div>

UI freezes in JetBrains IDEs aren’t always caused by heavy work on the event dispatch thread — our recent investigations reveal a frequent hidden culprit in plugins: long, non-cancellable read actions running in background threads. In this post, we break down why APIs like `ReadAction.compute` and `runReadAction` can silently block write actions and freeze the UI, how the IntelliJ Platform’s locking model makes this dangerous, and what patterns to avoid.

> **[UI Freezes and the Dangers of Non-Cancellable Read Actions in Background...](https://blog.jetbrains.com/platform/2026/03/ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/)**
>
> In JetBrains IDEs, UI freezes are often blamed on “heavy work on the EDT,” but our recent investigations show another common culprit in plugins: long, non-cancellable read actions running in backgroun

**Limited offer!** If you’re receiving UI freeze reports from users of your plugin, let us know in the comments below and share a link to your plugin on the JetBrains Marketplace — we’ll check whether users have reported any freezes to us, point you to the relevant issues, share thread dumps that we have, and even suggest practical fixes to help you keep your plugin fast and responsive!

---

<div class="post-metadata">

**Author:** ![jansorg](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/jansorg/32/52_2.png) [@jansorg](https://platform.jetbrains.com/u/jansorg)\
**Post date:** [March 19, 2026, 3:55pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/2 "2026-03-19T15:55:44Z")

</div>

First 🙂

Plugin BashSupport Pro, ID 13841, [https://plugins.jetbrains.com/plugin/13841](https://plugins.jetbrains.com/plugin/13841)  
(Not open source)

For example, a user reported that he uninstalled because it supposedly freezing the IDE. I couldn’t ask for more data because it was posted anonymously.

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![lemming](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/lemming/32/60_2.png) [@lemming](https://platform.jetbrains.com/u/lemming)\
**Post date:** [March 19, 2026, 9:44pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/3 "2026-03-19T21:44:46Z")

</div>

Second 🙂

Plugin Cursive, [https://plugins.jetbrains.com/plugin/8090-cursive](https://plugins.jetbrains.com/plugin/8090-cursive) (also not open source).

I’ve seen various cases where the IDE has complained about Cursive slowing things down. I’ve fixed the ones I have traces for, but if you’ve seen any more I’d appreciate any advice. I have lots of old bad code that I’m actively cleaning up now, so this would be really useful.

---

<div class="post-metadata">

**Author:** ![ldd](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/ldd/32/1238_2.png) [@ldd](https://platform.jetbrains.com/u/ldd)\
**Post date:** [March 20, 2026, 12:58am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/4 "2026-03-20T00:58:56Z")

</div>

flutterX: [https://plugins.jetbrains.com/plugin/18986-flutterx](https://plugins.jetbrains.com/plugin/18986-flutterx)

(Open source)

It uses a large number of `readAction` and `runReadAction`

---

<div class="post-metadata">

**Author:** ![insyncwithfoo](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/insyncwithfoo/32/158_2.png) [@insyncwithfoo](https://platform.jetbrains.com/u/insyncwithfoo)\
**Post date:** [March 21, 2026, 1:40am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/5 "2026-03-21T01:40:01Z")

</div>

Plugin: [RyeCharm](https://plugins.jetbrains.com/plugin/25230)  
Source code: [GitHub repository](https://github.com/InSyncWithFoo/ryecharm)

I don’t think I have received any freeze reports yet, but it would be useful to know if I have been writing good code.

---

<div class="post-metadata">

**Author:** ![joshtau](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/joshtau/32/1840_2.png) [@joshtau](https://platform.jetbrains.com/u/joshtau)\
**Post date:** [March 22, 2026, 9:21pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/6 "2026-03-22T21:21:03Z")

</div>

Why can’t plugin authors get these in stack exceptions? Because figuring out where the stack trace actually came from isn’t possible?

It sounds frustrating that Jetbrains has enforced coroutines and other changes without proper error reporting?

---

<div class="post-metadata">

**Author:** ![nifty.thoughts](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/nifty.thoughts/32/2728_2.png) [@nifty.thoughts](https://platform.jetbrains.com/u/nifty.thoughts)\
**Post date:** [March 22, 2026, 11:40pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/7 "2026-03-22T23:40:57Z")

</div>

> **[ANSI Highlighter Premium - IntelliJ IDEs Plugin | Marketplace](https://plugins.jetbrains.com/plugin/9707-ansi-highlighter-premium)**
>
> 5 USD per year - Try it before you buy it ANSI Highlighter Premium enables the fast rendering of ANSI control-code sequences in log files, regardless their size, from...

Curious to know if JB received freeze reports (or any other) for my plugin  
Did not receive any on my end

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [March 23, 2026, 9:48am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/8 "2026-03-23T09:48:32Z")

</div>

First of all, I would like to thank Joachim for the fantastic blog on error reporting

> **[How to implement error reporting in an IntelliJ plugin](https://www.plugin-dev.com/intellij/general/error-reporting/)**
>
> How to implement error reporting in your IntelliJ plugin.

Since BashSupport Pro uses `com.intellij.errorHandler` we seems do not receive any freezes but they should directly go to BashSupport Pro error handler. Be like Joachim, implement `errorHandler`!

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [March 23, 2026, 9:58am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/9 "2026-03-23T09:58:05Z")

</div>

Colin if you don’t mind here are a couple of freezes related to Cursive, and we will send you full reports and dumps privately.

## Non-cancellable read action in a background thread

Here is an excerpt from thread dumps. Look for `com.intellij.openapi.application.impl.ApplicationImpl.runReadAction` call. You probably know what to do:

```auto
"ApplicationImpl pooled thread 1901" prio=0 tid=0x0 nid=0x0 runnable
	...
	at com.intellij.util.indexing.FileBasedIndexEx.getValues(FileBasedIndexEx.java:133)
	at cursive.index$namespace_names.invokeStatic(index.clj:490)
	at cursive.index$namespace_names.invoke(index.clj:484)
	at cursive.stubs$stubs_required$fn$reify__22036.compute(stubs.clj:442)
	at com.intellij.openapi.application.impl.ApplicationImpl$$Lambda/0x000000700343f720.invoke(Unknown Source)
	at com.intellij.platform.locking.impl.NestedLocksThreadingSupport.runReadAction(NestedLocksThreadingSupport.kt:784)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:1038)
	at cursive.stubs$stubs_required$fn__22031.invoke(stubs.clj:441)
	at clojure.core.protocols$fn__8271.invokeStatic(protocols.clj:167)
	at clojure.core.protocols$fn__8271.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__8248.invokeStatic(protocols.clj:74)
	at clojure.core.protocols$fn__8248.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$reduce.invoke(core.clj:6947)
	at cursive.stubs$stubs_required.invokeStatic(stubs.clj:436)
	at cursive.stubs$stubs_required.invoke(stubs.clj:428)
	at clojure.lang.Var.invoke(Var.java:390)
	at cursive.api.DelayedFn.invoke(DelayedFn.java:36)
	at cursive.stubs.ReplStubsNotifications.checkStubs$lambda$2(Stubs.kt:215)
	at cursive.stubs.ReplStubsNotifications$$Lambda/0x0000007004eb0728.run(Unknown Source)
	at com.intellij.openapi.application.impl.ApplicationImpl$4.run(ApplicationImpl.java:326)
	at java.base@21.0.8/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	at com.intellij.util.concurrency.ContextCallable.lambda$call$1(ContextCallable.java:86)
	at com.intellij.util.concurrency.ContextCallable$$Lambda/0x0000007002649208.get(Unknown Source)
	at com.intellij.util.concurrency.ContextCallable.call(ContextCallable.java:95)
	at java.base@21.0.8/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at com.intellij.util.concurrency.ChildContext$runInChildContext$1.invoke(propagation.kt:167)
	at com.intellij.util.concurrency.ChildContext.runInChildContext(propagation.kt:173)
	at com.intellij.util.concurrency.ChildContext.runInChildContext(propagation.kt:167)
	at com.intellij.util.concurrency.ContextRunnable.run(ContextRunnable.java:27)
	at java.base@21.0.8/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
---------- EDT:
java.lang.Thread.State: TIMED_WAITING
 on com.intellij.openapi.progress.util.EternalEventStealer@1d088c11
	...
	at com.intellij.platform.locking.impl.NestedLocksThreadingSupport.runWriteAction(NestedLocksThreadingSupport.kt:921)
	at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1106)
	at com.intellij.psi.impl.PsiManagerImpl.dropPsiCaches(PsiManagerImpl.java:108)
	at com.intellij.lang.typescript.compiler.TypeScriptServiceRestarter.restartServices$lambda$1(TypeScriptServiceRestarter.kt:24)

```

## Waiting for lock under read action

This is an interesting issue, related to plugin own synchronization and locks.

One thread doing network on background, while holding an internal lock:

```auto
"ApplicationImpl pooled thread 9" prio=0 tid=0x0 nid=0x0 runnable
 (in native)
	at java.base@21.0.9/sun.nio.ch.Net.poll(Native Method)
	at java.base@21.0.9/sun.nio.ch.NioSocketImpl.park(NioSocketImpl.java:191)
	at java.base@21.0.9/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:280)
	at java.base@21.0.9/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:304)
	at java.base@21.0.9/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:346)
	at java.base@21.0.9/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:796)
	at java.base@21.0.9/java.net.Socket$SocketInputStream.read(Socket.java:1099)
	at java.base@21.0.9/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:489)
	at java.base@21.0.9/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:483)
	at java.base@21.0.9/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:70)
	at java.base@21.0.9/sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1461)
	at java.base@21.0.9/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:1066)
	at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
	at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
	at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
	at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
	at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
	at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
	at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
	at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.maven.wagon.shared.http.AbstractHttpClientWagon.execute(AbstractHttpClientWagon.java:1005)
	at org.apache.maven.wagon.shared.http.AbstractHttpClientWagon.fillInputData(AbstractHttpClientWagon.java:1162)
	at org.apache.maven.wagon.shared.http.AbstractHttpClientWagon.fillInputData(AbstractHttpClientWagon.java:1140)
	at org.apache.maven.wagon.StreamWagon.getInputStream(StreamWagon.java:126)
	at org.apache.maven.wagon.StreamWagon.getIfNewer(StreamWagon.java:88)
	at org.apache.maven.wagon.StreamWagon.get(StreamWagon.java:61)
	at org.eclipse.aether.transport.wagon.WagonTransporter$GetTaskRunner.run(WagonTransporter.java:523)
	at org.eclipse.aether.transport.wagon.WagonTransporter.execute(WagonTransporter.java:429)
	at org.eclipse.aether.transport.wagon.WagonTransporter.get(WagonTransporter.java:403)
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector$GetTaskRunner.runTask(BasicRepositoryConnector.java:466)
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:383)
	at org.eclipse.aether.util.concurrency.RunnableErrorForwarder.lambda$wrap$0(RunnableErrorForwarder.java:73)
	at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$$Lambda/0x000000f806527868.run(Unknown Source)
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector$DirectExecutor.execute(BasicRepositoryConnector.java:635)
	at org.eclipse.aether.connector.basic.BasicRepositoryConnector.get(BasicRepositoryConnector.java:280)
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:581)
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:478)
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:278)
	at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:255)
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:240)
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:171)
	at org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector.resolveCachedArtifactDescriptor(DfDependencyCollector.java:316)
	at org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector.getArtifactDescriptorResult(DfDependencyCollector.java:301)
	at org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector.processDependency(DfDependencyCollector.java:188)
	at org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector.processDependency(DfDependencyCollector.java:137)
	at org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector.process(DfDependencyCollector.java:125)
	at org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector.doCollectDependencies(DfDependencyCollector.java:107)
	at org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate.collectDependencies(DependencyCollectorDelegate.java:247)
	at org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector.collectDependencies(DefaultDependencyCollector.java:95)
	at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveDependencies(DefaultRepositorySystem.java:354)
	at cemerick.pomegranate.aether$resolve_dependencies_STAR_.invokeStatic(aether.clj:813)
	at cemerick.pomegranate.aether$resolve_dependencies_STAR_.doInvoke(aether.clj:770)
	at clojure.lang.RestFn.applyTo(RestFn.java:140)
	at clojure.core$apply.invokeStatic(core.clj:667)
	at clojure.core$apply.invoke(core.clj:662)
	at cursive.leiningen.project$resolve_hook$fn__1581.doInvoke(project.clj:220)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at cursive.leiningen.hooke$compose_hooks$fn__176.doInvoke(hooke.clj:43)
	at cursive.leiningen.hooke$run_hooks.invokeStatic(hooke.clj:49)
	at cursive.leiningen.hooke$run_hooks.invoke(hooke.clj:48)
	at cursive.leiningen.hooke$prepare_for_hooks$fn __181$fn__ 182.doInvoke(hooke.clj:57)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:33)
	at cemerick.pomegranate.aether$resolve_dependencies.invokeStatic(aether.clj:838)
	at cemerick.pomegranate.aether$resolve_dependencies.doInvoke(aether.clj:816)
	... 11 duplicate frames dropped
	at leiningen.core.classpath$get_dependencies_STAR_.invokeStatic(classpath.clj:289)
	at leiningen.core.classpath$get_dependencies_STAR_.invoke(classpath.clj:282)
	at clojure.lang.AFn.applyToHelper(AFn.java:165)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at cursive.leiningen.init$eval149$fn __150$fn__ 151.doInvoke(init.clj:32)
	at clojure.lang.RestFn.invoke(RestFn.java:460)
	at leiningen.core.classpath$get_dependencies$fn__6955.invoke(classpath.clj:338)
	at leiningen.core.classpath$get_dependencies.invokeStatic(classpath.clj:336)
	at leiningen.core.classpath$get_dependencies.doInvoke(classpath.clj:330)
	at clojure.lang.RestFn.invoke(RestFn.java:448)
	at cursive.leiningen.project$add_classpaths$fn__1629.invoke(project.clj:331)
	at cursive.leiningen.project$add_classpaths.invokeStatic(project.clj:330)
	at cursive.leiningen.project$add_classpaths.invoke(project.clj:318)
	at cursive.leiningen.project$project_info$fn__1860.invoke(project.clj:635)
	at clojure.core.protocols$fn__8279.invokeStatic(protocols.clj:167)
	at clojure.core.protocols$fn__8279.invoke(protocols.clj:123)
	at clojure.core.protocols$fn __8233$G__ 8228__8242.invoke(protocols.clj:19)
	at clojure.core.protocols$seq_reduce.invokeStatic(protocols.clj:31)
	at clojure.core.protocols$fn__8266.invokeStatic(protocols.clj:74)
	at clojure.core.protocols$fn__8266.invoke(protocols.clj:74)
	at clojure.core.protocols$fn __8207$G__ 8202__8220.invoke(protocols.clj:13)
	at clojure.core$reduce.invokeStatic(core.clj:6965)
	at clojure.core$reduce.invoke(core.clj:6947)
	at cursive.leiningen.project$project_info.invokeStatic(project.clj:618)
	at cursive.leiningen.project$project_info.invoke(project.clj:585)
	at cursive.leiningen.project$invoke.invokeStatic(project.clj:666)
	at cursive.leiningen.project$invoke.invoke(project.clj:660)
	at clojure.lang.Var.invoke(Var.java:390)
	at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:119)
	at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:112)
	at cursive.shim.ShimBootstrap$Shim.apply(ShimBootstrap.java:53)
	at cursive.leiningen.project.LeiningenProjectDetails.doGetDetails$lambda$1(ProjectDetails.kt:82)
	at cursive.leiningen.project.LeiningenProjectDetails$$Lambda/0x000000f8047360b8.invoke(Unknown Source)
	at cursive.shim.ShimProvider.withShim(Shim.kt:117)
	at cursive.leiningen.project.LeiningenProjectDetails.doGetDetails(ProjectDetails.kt:81)
	at cursive.leiningen.project.LeiningenProjectDetails.doGetDetails(ProjectDetails.kt:73)
	at cursive.build.BuildSystemProjectDetails.getProjectDetails(BuildSystem.kt:40)
	at cursive.build.BuildSystemProjectsManager.reimportAllProjects$lambda$0$0(BuildSystemManager.kt:175)
	at cursive.build.BuildSystemProjectsManager$$Lambda/0x000000f80444dc40.run(Unknown Source)
	at cursive.build.BuildSystemUtil$runTask$1$1.run(BuildSystemUtil.kt:139)

```

Another thread having read lock, tries to access this `cursive.leiningen.project.LeiningenProjectDetails@2ae18049`:

```auto
---------- BLOCKED0 "ApplicationImpl pooled thread 5" prio=0 tid=0x0 nid=0x0 blocked:
java.lang.Thread.State: BLOCKED
 on cursive.leiningen.project.LeiningenProjectDetails@2ae18049 owned by "ApplicationImpl pooled thread 9" Id=190
	at cursive.build.BuildSystemProjectDetails.getProjectDetails(BuildSystem.kt:38)
	at cursive.runner.UtilsKt.checkProfiles(Utils.kt:314)
	at cursive.runner.BaseJvmClojureRunConfiguration.checkConfiguration(ClojureRunnerBase.kt:259)
	at cursive.repl.runner.LocalConfiguration.checkConfiguration(LocalReplRunConfigurations.kt:195)
	at com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl.checkSettings$lambda$0$0(RunnerAndConfigurationSettingsImpl.kt:363)
	at com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl$$Lambda/0x000000f80411f480.invoke(Unknown Source)
	at com.intellij.execution.impl.ExecutionManagerImpl$Companion.withEnvironmentDataContext(ExecutionManagerImpl.kt:108)
	at com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl.checkSettings$lambda$0(RunnerAndConfigurationSettingsImpl.kt:362)
	at com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl$$Lambda/0x000000f804112e90.call(Unknown Source)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$OTelMonitor.callWrapped(NonBlockingReadActionImpl.java:929)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$OTelMonitor$MonitoredComputation.call(NonBlockingReadActionImpl.java:961)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.insideReadAction(NonBlockingReadActionImpl.java:685)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.attemptComputation(NonBlockingReadActionImpl.java:632)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$executeSynchronously$3(NonBlockingReadActionImpl.java:570)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission$$Lambda/0x000000f80411e948.invoke(Unknown Source)
	at com.intellij.concurrency.ThreadContext.installThreadContext(threadContext.kt:305)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$executeSynchronously$5(NonBlockingReadActionImpl.java:569)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission$$Lambda/0x000000f804113340.get(Unknown Source)
	at com.intellij.openapi.application.impl.NbraUtilKt.runSynchronousNonBlockingReadActionWithCompensation$lambda$0(nbraUtil.kt:15)
	at com.intellij.openapi.application.impl.NbraUtilKt$$Lambda/0x000000f80411b830.invoke(Unknown Source)
	at kotlinx.coroutines.internal.intellij.IntellijCoroutines.runAndCompensateParallelism-VtjQ1oo(intellij.kt:91)
	at com.intellij.util.IntelliJCoroutinesFacade.runAndCompensateParallelism-VtjQ1oo(IntelliJCoroutinesFacade.kt:45)
	at com.intellij.openapi.application.impl.NbraUtilKt.runSynchronousNonBlockingReadActionWithCompensation(nbraUtil.kt:14)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.executeSynchronously(NonBlockingReadActionImpl.java:556)
	at com.intellij.openapi.application.impl.NonBlockingReadActionImpl.executeSynchronously(NonBlockingReadActionImpl.java:260)
	at com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl.checkSettings(RunnerAndConfigurationSettingsImpl.kt:370)

```

And finally EDT is stuck, because cannot obtain write (waiting for read lock owner):

```auto
---------- EDT:
java.lang.Thread.State: TIMED_WAITING
 on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@27d31682
	...
	at com.intellij.platform.locking.impl.NestedLocksThreadingSupport.runWriteAction(NestedLocksThreadingSupport.kt:997)
	at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1142)
	at com.intellij.openapi.project.DumbServiceImpl.decrementDumbCounter(DumbServiceImpl.kt:292)
	at com.intellij.openapi.project.DumbServiceImpl.access$decrementDumbCounter(DumbServiceImpl.kt:49)

```

Here you may try `ProgressIndicatorUtils.awaitWithCheckCanceled(Lock)` or invent something like this, to await locks in a cancellable manner.

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [March 23, 2026, 10:01am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/10 "2026-03-23T10:01:03Z")

</div>

> [@joshtau](#):
>
> Why can’t plugin authors get these in stack exceptions?

They definitely can! We receive only fraction of reports when a cause of a freeze is unclear. To improve your error reporting please do not forget to implement a `errorHandler`.

> **[How to implement error reporting in an IntelliJ plugin](https://www.plugin-dev.com/intellij/general/error-reporting/)**
>
> How to implement error reporting in your IntelliJ plugin.

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [March 23, 2026, 10:48am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/11 "2026-03-23T10:48:39Z")

</div>

For FlutterX I have not managed to find any freezes in our reporting, most likely because the audience of the plugin is mostly Android Studio users. We do not control the error reporting in Android Studio, issue reports there go to Google Inc.

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [March 23, 2026, 1:14pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/12 "2026-03-23T13:14:54Z")

</div>

For RyeCharm too, unfortunately not yet on our radars

---

<div class="post-metadata">

**Author:** ![lemming](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/lemming/32/60_2.png) [@lemming](https://platform.jetbrains.com/u/lemming)\
**Post date:** [March 24, 2026, 3:41am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/13 "2026-03-24T03:41:47Z")

</div>

Thanks Yuriy, the first is already fixed in the latest Cursive version, I’ll look into the second one.

---

<div class="post-metadata">

**Author:** ![damien.urruty](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/damien.urruty/32/2741_2.png) [@damien.urruty](https://platform.jetbrains.com/u/damien.urruty)\
**Post date:** [March 25, 2026, 11:25am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/14 "2026-03-25T11:25:58Z")

</div>

Hello @yuriy.artamonov,

We would also be interested to get insights for SonarQube for IDE: [https://plugins.jetbrains.com/plugin/7973-sonarqube-for-ide](https://plugins.jetbrains.com/plugin/7973-sonarqube-for-ide)

Thanks!

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [March 25, 2026, 4:43pm UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/15 "2026-03-25T16:43:11Z")

</div>

Really glad you asked! Here are some freezes on our radars.

## Non-cancellable ReadAction in SonarLintIntelliJClient

Here is one of really visible examples (many repetettive reports), where `SonarLintIntelliJClient` runs `ReadAction.compute` on a background thread, leading to frequent freezes.

```auto
...
	at com.intellij.openapi.roots.TestSourcesFilter.isTestSources(TestSourcesFilter.java:32)
	at org.sonarlint.intellij.SonarLintIntelliJClient.toClientFileDto$lambda$1(SonarLintIntelliJClient.kt:889)
	at org.sonarlint.intellij.SonarLintIntelliJClient$$Lambda/0x000002472f1a3838.compute(Unknown Source)
	at org.sonarlint.intellij.common.ui.ReadActionUtils$Companion.computeReadActionSafely$lambda$4(ReadActionUtils.kt:80)
	at org.sonarlint.intellij.common.ui.ReadActionUtils$Companion$$Lambda/0x000002472f188258.compute(Unknown Source)
	at com.intellij.openapi.application.impl.AppImplKt$rethrowCheckedExceptions$2.invoke(appImpl.kt:106)
	at com.intellij.platform.locking.impl.NestedLocksThreadingSupport.runReadAction(NestedLocksThreadingSupport.kt:784)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:1043)
	at com.intellij.openapi.application.ReadAction.compute(ReadAction.java:66)
	at org.sonarlint.intellij.common.ui.ReadActionUtils$Companion.computeReadActionSafely(ReadActionUtils.kt:79)
	at org.sonarlint.intellij.SonarLintIntelliJClient.toClientFileDto(SonarLintIntelliJClient.kt:884)
	at org.sonarlint.intellij.SonarLintIntelliJClient.listModuleFiles(SonarLintIntelliJClient.kt:825)
	at org.sonarlint.intellij.SonarLintIntelliJClient.listFiles(SonarLintIntelliJClient.kt:787)
	at org.sonarsource.sonarlint.core.rpc.client.SonarLintRpcClientImpl.lambda$listFiles$31(SonarLintRpcClientImpl.java:343)
	at org.sonarsource.sonarlint.core.rpc.client.SonarLintRpcClientImpl$$Lambda/0x000002472f12cfd8.apply(Unknown Source)
	at org.sonarsource.sonarlint.core.rpc.client.SonarLintRpcClientImpl.lambda$requestAsync$1(SonarLintRpcClientImpl.java:126)
	at org.sonarsource.sonarlint.core.rpc.client.SonarLintRpcClientImpl$$Lambda/0x000002472f0ad270.apply(Unknown Source)
	at java.base@21.0.9/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
	at java.base@21.0.9/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482)
	at java.base@21.0.9/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base@21.0.9/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base@21.0.9/java.lang.Thread.runWith(Thread.java:1596)
	at java.base@21.0.9/java.lang.Thread.run(Thread.java:1583)

```

Please try `ReadAction.nonBlocking` or coroutines `readAction` as an alternative.

## Non-cancellable ReadAction in BackendService

This is a similar problem but with a different stack:

```auto
...
	at com.intellij.openapi.roots.TestSourcesFilter.isTestSources(TestSourcesFilter.java:32)
	at org.sonarlint.intellij.core.BackendService.gatherClientFiles$lambda$121$lambda$120$lambda$119(BackendService.kt:1114)
	at org.sonarlint.intellij.core.BackendService$$Lambda/0x0000000138ff9000.compute(Unknown Source)
	at org.sonarlint.intellij.common.ui.ReadActionUtils$Companion.computeReadActionSafely$lambda$5(ReadActionUtils.kt:80)
	at org.sonarlint.intellij.common.ui.ReadActionUtils$Companion$$Lambda/0x0000000136437bc0.compute(Unknown Source)
	at com.intellij.openapi.application.impl.AppImplKt$rethrowCheckedExceptions$2.invoke(appImpl.kt:106)
	at com.intellij.platform.locking.impl.NestedLocksThreadingSupport.runReadAction(NestedLocksThreadingSupport.kt:784)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:1043)
	at com.intellij.openapi.application.ReadAction.compute(ReadAction.java:66)
	at org.sonarlint.intellij.common.ui.ReadActionUtils$Companion.computeReadActionSafely(ReadActionUtils.kt:79)
	at org.sonarlint.intellij.core.BackendService.gatherClientFiles(BackendService.kt:1109)
	at org.sonarlint.intellij.core.BackendService.updateFileSystem(BackendService.kt:1084)
	at org.sonarlint.intellij.fs.DefaultVirtualFileSystemEventsHandler.forwardEvents(DefaultVirtualFileSystemEventsHandler.kt:59)
	at org.sonarlint.intellij.fs.DefaultVirtualFileSystemEventsHandler.forwardEventsAsync$lambda$1(DefaultVirtualFileSystemEventsHandler.kt:47)
	at org.sonarlint.intellij.fs.DefaultVirtualFileSystemEventsHandler$$Lambda/0x00000001361e2b18.run(Unknown Source)
	at java.base@21.0.9/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	at java.base@21.0.9/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base@21.0.9/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base@21.0.9/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base@21.0.9/java.lang.Thread.runWith(Thread.java:1596)
	at java.base@21.0.9/java.lang.Thread.run(Thread.java:1583)

```

We will contact you additionally with raw dumps we have and some stats about users and frequency!

---

<div class="post-metadata">

**Author:** ![yuriy.artamonov](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/yuriy.artamonov/32/48_2.png) [@yuriy.artamonov](https://platform.jetbrains.com/u/yuriy.artamonov)\
**Post date:** [September 6, 2026, 7:27am UTC](https://platform.jetbrains.com/t/blog-post-ui-freezes-and-the-dangers-of-non-cancellable-read-actions-in-background-threads/3895/16 "2026-09-06T07:27:20Z")

</div>

Split this topic on September 6, 2026, 7:27am UTC

A post was split to a new topic: [Update of action in RD with suspend RPC call](https://platform.jetbrains.com/t/update-of-action-in-rd-with-suspend-rpc-call/5014)
