LocalInspectionTool ProblemDescriptor not displayed in Problems Window/Hover for Shell Script (.sh) files when plugin is zip-installed (works in RunID)

Problem description:

We are developing an IntelliJ plugin that uses LocalInspectionTool to report security vulnerabilities detected by an external scanner. The inspection works correctly for most file types (.json, .java, .py, .cs), but for Shell Script (.sh) files, the ProblemDescriptor objects are not displayed in the Problems window or as hover tooltips when the plugin is installed from a zip file.

What Works:

  • :white_check_mark: Vulnerabilities are correctly detected in .sh files

  • :white_check_mark: Lines are highlighted in the editor (via custom MarkupModel.addRangeHighlighter())

  • :white_check_mark: Gutter icons appear in the left margin (via custom GutterIconRenderer)

  • :white_check_mark: Our checkFile() method returns valid ProblemDescriptor[] (confirmed via logging)

  • :white_check_mark: Everything works correctly when running the plugin via runIde Gradle task

What Doesn’t Work (only for .sh files):

  • :cross_mark: Problems Window shows no entries

  • :cross_mark: Hover tooltips don’t appear when hovering over highlighted lines

Critical Finding:

The issue occurs only when the plugin is installed from a zip file, not when running via runIde. This happens regardless of IDE version:

Technical Details:

Our inspection extends LocalInspectionTool and is registered in plugin.xml as: <<localInspection implementationClass="com.checkmarx.intellij.devassist.inspection.CxOneAssistInspection" displayName="Checkmarx One Assist" groupName="Checkmarx" shortName="CxOneAssist" enabledByDefault="true"/>

We create ProblemDescriptor using:

InspectionManager.createProblemDescriptor(
psiFile, // PsiFile (ShFile for .sh files)
textRange, // TextRange for the problem line
description, // HTML description
ProblemHighlightType.GENERIC_ERROR,
isOnTheFly,
localQuickFixes
);

What We’ve Tried (All Failed):

  1. :cross_mark: Using PsiElement instead of PsiFile with relative TextRange

  2. :cross_mark: Adding level="WARNING" and runForWholeFile="true" to inspection registration

  3. :cross_mark: Verified PsiFile instance consistency (same instance used throughout)

  4. :cross_mark: Confirmed PsiFile.isValid() returns true

  5. :cross_mark: Verified Shell Script plugin is installed and enabled

Debug Logging Confirms:

RTS-DEBUG: File: deploy.sh, PsiFile class: com.intellij.sh.psi.ShFile, TextRange: (0,53), HighlightType: GENERIC_ERROR
RTS-DEBUG: Returning 9 problem descriptors for file: deploy.sh
The ProblemDescriptor objects are valid and being returned, but IntelliJ’s inspection framework is not displaying them.

Steps to reproduce:

  1. Create an IntelliJ plugin with a LocalInspectionTool implementation

  2. In checkFile(), return ProblemDescriptor[] for .sh files using InspectionManager.createProblemDescriptor(psiFile, textRange, ...)

  3. Build the plugin using ./gradlew buildPlugin

  4. Install the plugin from the zip file (Settings → Plugins → :gear: → Install Plugin from Disk)

  5. Open a .sh file that triggers the inspection

  6. Observe that:

    • The Problems window is empty (no entries for .sh file)

    • Hover tooltips don’t appear

  7. Compare with ./gradlew runIde where everything works correctly

Environment:

  • Product: IntelliJ IDEA Community Edition & PyCharm Professional

  • Product Versions Tested:

    • IntelliJ IDEA 2022.2.1 (Community Edition)

    • PyCharm 2025.2.0.1

  • Operating System: Windows 11

  • Plugin Build Configuration:

    • org.jetbrains.intellij plugin version: 1.17.4

    • Target IntelliJ version: 2022.2.1

    • Java sourceCompatibility: 11 (also tested with 17)

  • Shell Script Plugin: Installed and enabled

  • Plugin Dependencies: Only com.intellij.modules.platform

Question

  • Is there a known issue with LocalInspectionTool and Shell Script files that causes ProblemDescriptor objects to not be displayed in the Problems window when the plugin is zip-installed? Is there a different approach we should use for Shell Script files, such as ExternalAnnotator?

Hello,
please provide a minimal working plugin example, so it can be reproduced.

My guess would be this: intellij-community/plugins/sh/core/src/com/intellij/sh/ShErrorFilter.java at 6d1f55f16043ad48f67762c50ab1035e0a589ca7 · JetBrains/intellij-community · GitHub

If it’s working in internal mode (perhaps enabled via runIde?), then it’s likely.

2 Likes

Hi @jansorg,

Thank you for pointing us to ShErrorFilter.java - you were absolutely correct!

We confirmed that the filter blocks highlights with severity >= WARNING for .sh files when isInternal() is false. This explains why our LocalInspectionTool works in RunIDE (internal mode) but not when the plugin is zip-installed.

Our plugin uses ProblemHighlightType.GENERIC_ERROR to report security vulnerabilities, which gets filtered out in production mode.

We’ve implemented a workaround using ProblemHighlightType.WEAK_WARNING specifically for .sh files to bypass the filter. While this makes the issues visible in the Problems window and hover tooltips, the disadvantage is that security vulnerabilities now appear with a warning icon instead of an error icon - which doesn’t accurately represent their severity.

Do you know if there’s a better approach? For example:

  1. Is there a way to register an exception to ShErrorFilter for third-party plugins?

  2. Would using ExternalAnnotator instead of LocalInspectionTool bypass this filter?

  3. Is this filter behavior intentional for all third-party inspections, or is it meant only for the Shell Script plugin’s own parser errors?

Any guidance would be appreciated!

Implementing your own <daemon.highlightInfoFilter order="first" ...> is not possible, because the first filter returning false turns off highlighting. You can’t override that to true.

If I’m not mistaken ProblemHighlightType.GENERIC_ERROR means to use the configured highlighting of your inspection, e.g. info/warning/error.
Can’t you use ProblemHighlightingType.ERROR, perhaps just for shell files?

Not an official answer, but GENERIC_ERROR_OR_WARNING uses configuration in the Inspection settings. The same goes for GENERIC_ERROR, but with error-ish highlighting.