# Stricter plugin verification in IntelliJ Platform Gradle Plugin 2.15.0

**URL:** <https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169>\
**Category:** Announcements\
**Tags:** plugin-development, intellij-platform-gr\
**Created:** [April 28, 2026, 2:52pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169 "2026-04-28T14:52:38Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![robert.novotny](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/robert.novotny/32/2046_2.png) [@robert.novotny](https://platform.jetbrains.com/u/robert.novotny)\
**Post date:** [April 28, 2026, 2:52pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/1 "2026-04-28T14:52:39Z")

</div>

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](https://github.com/JetBrains/intellij-platform-gradle-plugin/releases/tag/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.

```kotlin
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.

---

<div class="post-metadata">

**Author:** ![jojoatxgme](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/jojoatxgme/32/1550_2.png) [@jojoatxgme](https://platform.jetbrains.com/u/jojoatxgme)\
**Post date:** [May 4, 2026, 10:44pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/2 "2026-05-04T22:44:50Z")

</div>

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](https://youtrack.jetbrains.com/issue/IJPL-176605/Incorrect-use-of-OverrideOnly-in-LeafOccurrenceMapper) and [MP-7233](https://youtrack.jetbrains.com/issue/MP-7233/ApiStatus.OverrideOnly-Do-not-highlight-static-methods).

---

<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:** [May 14, 2026, 4:18pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/3 "2026-05-14T16:18:46Z")

</div>

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](https://youtrack.jetbrains.com/issue/IJPL-243914)

---

<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:** [May 14, 2026, 4:36pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/4 "2026-05-14T16:36:50Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Nicholas\_Hubbard](https://avatars.discourse-cdn.com/v4/letter/n/9fc348/32.png) [@Nicholas\_Hubbard](https://platform.jetbrains.com/u/Nicholas_Hubbard)\
**Post date:** [May 22, 2026, 2:48pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/5 "2026-05-22T14:48:21Z")

</div>

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).

---

<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:** [May 23, 2026, 8:34am UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/6 "2026-05-23T08:34:54Z")

</div>

> [@Nicholas\_Hubbard](#):
>
> `runReadActionBlocking`

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

> **[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

**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.

---

<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:** [May 23, 2026, 8:35am UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/7 "2026-05-23T08:35:20Z")

</div>

> [@Nicholas\_Hubbard](#):
>
> an experimental API warning against `Pointer` in `261` despite it being used by the new target API.

This is resolved in the upcoming 2026.2 release

---

<div class="post-metadata">

**Author:** ![Nicholas\_Hubbard](https://avatars.discourse-cdn.com/v4/letter/n/9fc348/32.png) [@Nicholas\_Hubbard](https://platform.jetbrains.com/u/Nicholas_Hubbard)\
**Post date:** [May 25, 2026, 1:20pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/8 "2026-05-25T13:20:28Z")

</div>

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?

---

<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:** [May 25, 2026, 1:22pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/9 "2026-05-25T13:22:06Z")

</div>

> [@Nicholas\_Hubbard](#):
>
> method to 252 and 253 so that we don’t get incompatibility errors for those versions?

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

---

<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:** [May 25, 2026, 1:22pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/10 "2026-05-25T13:22:46Z")

</div>

> [@Nicholas\_Hubbard](#):
>
> `CodeVisionPlaceholderCollector`

It should receive a review from us soon

---

<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:** [May 25, 2026, 1:24pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/11 "2026-05-25T13:24:35Z")

</div>

> [@Nicholas\_Hubbard](#):
>
> I don’t need to distribute my plugin publicly

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.

---

<div class="post-metadata">

**Author:** ![Nicholas\_Hubbard](https://avatars.discourse-cdn.com/v4/letter/n/9fc348/32.png) [@Nicholas\_Hubbard](https://platform.jetbrains.com/u/Nicholas_Hubbard)\
**Post date:** [May 25, 2026, 1:52pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/12 "2026-05-25T13:52:55Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![jonathanlermitage.1](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@jonathanlermitage.1](https://platform.jetbrains.com/u/jonathanlermitage.1)\
**Post date:** [May 25, 2026, 2:09pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/13 "2026-05-25T14:09:06Z")

</div>

Do you think [Statistics: product versions in use | JetBrains Marketplace Documentation](https://plugins.jetbrains.com/docs/marketplace/product-versions-in-use-statistics.html) 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](https://platform.jetbrains.com/t/justifying-split-mode-architecture-for-third-party-plugin-authors/4341/4)  
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).

---

<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:** [May 25, 2026, 2:15pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/14 "2026-05-25T14:15:48Z")

</div>

> [@jonathanlermitage.1](#):
>
> So, in my opinion, it is therefore worth supporting at least the 253 IDEs.
> 
> * * *

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

---

<div class="post-metadata">

**Author:** ![jonathanlermitage.1](https://avatars.discourse-cdn.com/v4/letter/j/e480ec/32.png) [@jonathanlermitage.1](https://platform.jetbrains.com/u/jonathanlermitage.1)\
**Post date:** [May 25, 2026, 2:25pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/15 "2026-05-25T14:25:22Z")

</div>

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_ 😁.

---

<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:** [May 25, 2026, 2:26pm UTC](https://platform.jetbrains.com/t/stricter-plugin-verification-in-intellij-platform-gradle-plugin-2-15-0/4169/16 "2026-05-25T14:26:05Z")

</div>

> [@jonathanlermitage.1](#):
>
> will be updated soon? This would be interesting.

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
