Read action on BGT for find usages

Hi! I have several questions regarding searching for usages in queries. I have the following code:

abstract class FormSymbolUsageSearchQuery<T : FormSymbol<*>>(
    protected val resolveTarget: T,
    protected val searchScope: SearchScope,
) : AbstractQuery<FormSymbolUsage>() {

    override fun processResults(consumer: Processor<in FormSymbolUsage>): Boolean {
        val progressTitle = SolarBundle.message("form.symbol.query.searching", resolveTarget.targetName)
        if (ApplicationManager.getApplication().isDispatchThread) {
            runWithModalProgressBlocking(resolveTarget.project, progressTitle) {
                readAction {
                    processDeclarationsAndReferences(consumer)
                }
            }

            return true
        }

        runBlockingCancellable {
            withBackgroundProgress(resolveTarget.project, progressTitle) {
                readAction {
                    processDeclarationsAndReferences(consumer)
                }
            }
        }

        return true
    }

...

This query works fine for highlighting usages of symbols, renaming and finding usages by ctrl-clicking on the symbol. But as soon as I invoke “Find Usages“ on a symbol, I get:

2025-10-26 22:04:22,779 \[  60399\] SEVERE - #c.i.o.p.Task - must run find usages under progress
java.lang.IllegalStateException: must run find usages under progress
at com.intellij.usages.impl.SearchForUsagesRunnable.lambda$searchUsages$11(SearchForUsagesRunnable.java:368)
at com.intellij.psi.impl.search.Layer.runLayer$lambda$0(helper.kt:149)
at com.intellij.psi.impl.search.HelperKt.runQueryRequest$lambda$4(helper.kt:303)
at com.intellij.psi.impl.search.HelperKt.runQueryRequest$lambda$5(helper.kt:300)
at com.intellij.util.AbstractQuery.lambda$threadSafeProcessor$1(AbstractQuery.java:69)
at com.solanteq.solar.plugin.form.common.symbol.FormSymbolUsageSearchQuery.processReferences(FormSymbolUsageSearchQuery.kt:90)

My first question is: why progress indicator is not available inside the read action and how to fix it?

I also kinda struggle with coroutines and threading model in general. So there are other questions:

  • Is it correct to call runWithModalProgressBlocking on EDT? It’s invoked on EDT when I try to rename the symbol in-place.
  • Is it correct to wrap the whole search process into a readAction? If not, what are the alternatives? Wrap every single read in a separate readAction, and make processDeclarationsAndReferences suspending (and all inner calls)?