Stricter plugin verification in IntelliJ Platform Gradle Plugin 2.15.0

As part of our ongoing effort to improve plugin quality and compatibility, the default plugin verification mode is now stricter.
Starting with IntelliJ Platform Gradle Plugin 2.15.0, the verifyPlugin task fails the Gradle build when it detects:

  • plugin compatibility problems with target IDEs,
  • Internal API usage,
  • Override-Only API usage.

How to Opt Out

We understand that some established plugins may still rely on Internal or Override-Only APIs and may not have a quick migration path.
In these cases, you can customize verification behavior by setting failureLevel in the intellijPlatform extension of your Gradle build script.

intellijPlatform {
    pluginVerification {
        failureLevel = listOf(
            FailureLevel.COMPATIBILITY_PROBLEMS,
            FailureLevel.INTERNAL_API_USAGES,
        )
    }
}

By default, failureLevel is now set to:

  • FailureLevel.COMPATIBILITY_PROBLEMS,
  • FailureLevel.INTERNAL_API_USAGES,
  • FailureLevel.OVERRIDE_ONLY_API_USAGES.

JetBrains Marketplace Verification

These changes affect only local Gradle builds.
JetBrains Marketplace verification rules remain unchanged for now.
New plugins are still prohibited from using Internal or Override-Only APIs, and such usage causes verification errors that block publication.

3 Likes

I want to highlight that I get a false-positive from OVERRIDE_ONLY_API_USAGES since about one year for LeafOccurrenceMapper.withPointer. See also IJPL-176605 and MP-7233.

1 Like

How do we go about getting approval/noted about usage of internal APIs, e.g we rely on things such as https://youtrack.jetbrains.com/issue/IJPL-243914

This works as follows:

  • once we make something public API (at least Experimental)
  • and we release a public release build with such changes
  • and new verification on Marketplace starts

It will know that this is public API now and will not alert you on usages with previous platform versions, it will not be a problem for approvals anymore.

So our goal here is to identify exactly which API do you need and improve, promote that to Experimental and then to stable.

I get the following false positives. My target is currently 252, but I’m considering going up to 261 on my trunk branch.

  • A deprecation warning about PsiElement.checkAdd(PsiElement) and PsiElement.checkDelete() because my navigation items override NavigatablePsiElement. I don’t override these directly (I use Kotlin by delegation to the underlying PsiElement) or call these methods.
  • runReadActionBlocking is not available in 252 or 253; I thought there was supposed to be a shim for these? Maybe I’m wrong.
  • I moved to the new documentation target API already, and I expect Experimental API warnings from 252 and 253, but I also get an experimental API warning against Pointer in 261 despite it being used by the new target API.
  • I use DaemonBoundCodeVisionProvider extensively, and get a false positive Internal API error for CodeVisionPlaceholderCollector despite not referencing it in my Code Vision providers at all.

If anyone from JetBrains wants to get on a Zoom or Teams call, I would be happy to show what I do with my plugin, or provide the problems report from Gradle. I am comfortable using Internal APIs since this plugin is not yet released, but it is available internally for anyone to use (and I anticipate adding it to our hackathon this year to get the plugin out for others to use).

This is a direct replacement of runReadAction to explicitly show you that you are going to block read lock for the entire length of an operation. We are not removing runReadAction any time soon. But this deprecation is a call to action on

Note on API deprecation: As of the 2026.1 versions of our IDEs, we are deprecating runReadAction and ReadAction.compute in favor of the more explicit runReadActionBlocking and ReadAction.computeBlocking. Instead of just replacing usages, consider ReadAction.nonBlocking for background processing without suspend or readAction for suspend contexts.

This is resolved in the upcoming 2026.2 release

1 Like

Makes sense. Most of my work that I use it for has to be blocking but it’s never blocking for more than a few milliseconds. Is there a plan to add the runReadActionBlocking method to 252 and 253 so that we don’t get incompatibility errors for those versions?

And is there a solution for checkAdd/checkDelete and CodeVisionPlaceholderCollector? Again, I don’t need to distribute my plugin publicly, but if we get these internal/experimental warnings from using public supported APIs, will there be a solution?

No, it unfortunately does not make sense as most of users have already upgraded to 2026.1 release

1 Like

It should receive a review from us soon

Please be aware that if something is ApiStatus.Internal that means we do not care of any compatibility, it may break or disappear any time and with any update. It basically means – not an API, used as a drop-in replacement for internal modifier by us.

All good, I’m happy to update quickly. I live on the bleeding edge. Regarding the backport, I’ll target 261 as my minimum at this point. Thanks for your input!

Do you think Statistics: product versions in use | JetBrains Marketplace Documentation will be updated soon? This would be interesting.

For me, 2025 IDEs still represent 30% of my (38k) users. More exactly: 23% of 253 and 7% of 252.

Both metrics are useful, but I think it’s important to keep in mind they may change, depending on what you count:

  • IDEs in general
  • IDEs that have 3rd-party plugins installed. I know many developers who are not allowed to install 3rd-party plugins, and many others never tried to install a 3rd-party plugin (some of them are not comfortable with their IDE), which can explain the difference with IDEs in general. As a plugin developer, I prefer to focus (and support) IDEs that have 3rd-party plugins installed.
  • this may also vary depending on the 3rd-party plugin (based on its type—plugin or theme—and its features)
  • the targeted IDEs. Per example, the current stable version of Android Studio (Panda 4) is based on IJ 253.

So, in my opinion, it is therefore worth supporting at least the 253 IDEs.


Other subject: this also leads me to Justifying split mode architecture for third party plugin authors - #4 by yuriy.artamonov
The top 10 large enterprise customers is interesting, but do they use (our) 3rd-party plugins? Things like that. I think you understand why I’m not a big fan of statistics. They are useful, but difficult to interpret, especially when we don’t know the details (but I completely understand they have to stay private, unfortunately).

1 Like

Depends on what do you mean by supporting, for well established plugins with a stable set of features, usually it makes sense to only add feature for latest stable release and do not worry about people who do not upgrade IDE

Sure, if you can afford that. It clearly depends on the plugin and its customers.

This is more complex for Android Studio, or companies that forces specific versions of IDEs. Just an example: I worked for a major Quebec-based company three years ago: developers were not allowed to install anything except from an internal catalog. They were using an old version of IntelliJ Ultimate (~1 year late). Given this situation, I can’t blame users for using an older IDE, and I don’t want to treat them like second-class citizens. I’m saying that because they were using one of my plugins. It was a great experience.

So, yeah, it depends :grin:.

I am so sorry, I got buried under load from performance issues in plugins and could not publish it timely, but we already got new numbers for it

1 Like