Running Quick Fix actions from the UI thread


In my plugin, I have a long-running task after which I want to show a Quick Fix action. I've read in this doc about the threading rules and I wanted to use executeOnPooledThread() to run the task in the background and then runReadAction() to switch to the UI thread. Unfortunately, using holder.registerProblem() doesn't show a Quick Fix on the UI (even though it works if not wrapped in executeOnPooledThread() and runReadAction()).

I have the following code:

class YamlElementVisitor(
private val holder: ProblemsHolder,
private val isOnTheFly: Boolean,
) : YamlPsiElementVisitor() {

override fun visitFile(file: PsiFile) {

ApplicationManager.getApplication().executeOnPooledThread {
           ... long running task in the background thread ...

ApplicationManager.getApplication().runReadAction {
... showing quick fix from the UI thread ...

What's the correct way of doing this?


Could you please explain what this "long-running task" does and from where this visitor is invoked (local inspection?!)?

I assume its results will determine availability/behavior of eventually added quick fix?


The long-running task is making an HTTP request. After analysing the YAML file, I need to make the request to the API and show a quick fix based on the results. 

Currently, for showing a quick fix I'm using LocalQuickFixOnPsiElement (you can see the full code here).

Thanks for any suggestions!


Code analysis that does heavy lifting should preferrably use "External Annotator" API instead. It allows better decoupling of heavy process vs actual code annotation,

I'd strongly suggest to consider migrating this use case.


I migrated my LocalInspectionTool to use ExternalAnnotator instead (as suggested) and it actually fixed my problem. Thanks for your help!


Please sign in to leave a comment.