Kotlin K2 breaks template injection with MultiHostInjector

Hello everyone!
JTE (jte.gg) is a fast, type-safe templating engine for Spring Boot with Java and Kotlin. Its IntelliJ plugin makes server-side rendering development genuinely smooth. However, the Kotlin/K2 compiler in IntelliJ breaks key features, making JTE effectively unusable in Kotlin projects now that K1 is deprecated or being phased out. I’d love to contribute a fix, and I’m looking for guidance on the correct K2 approach and any interim workarounds.


TL;DR

  • When Kotlin K2 mode is enabled in IntelliJ, the JTE IntelliJ plugin loses core functionality in Kotlin templates (*.kte): imports flag errors, references don’t resolve, and completion fails (syntax highlighting still works).
  • The plugin injects Kotlin into templates via com.intellij.lang.injection.MultiHostInjector. In K2, this appears to no longer behave like it did under K1 (e.g., injected fragments are treated as code fragments where imports are “forbidden”).
  • Hoping for guidance on the correct way to implement Kotlin language injection and symbol resolution under K2, or any known workarounds.

GitHub issue:
Add support for new Kotlin K2 mode. · Issue #49 · casid/jte-intellij · GitHub

Environment

  • IntelliJ IDEA: observed in 2024.2, 2024.3, and 2025.1 (where K2 is enabled by default).
  • Kotlin K2 mode: enabled.
  • JTE IntelliJ plugin: 2.2.x (author marked K2-compatible; removed internal API usage).
  • Result: With K2 on, autocompletion and imports resolution inside JTE Kotlin templates are broken; with K2 off, plugin works but this is no longer a viable long-term approach due to K1 deprecation.

What breaks under K2

  • Imports in injected Kotlin regions inside JTE templates show errors similar to: “Package directive and imports are forbidden in code fragments in injected files.”
  • Symbol resolution/completion within the injected Kotlin context fails.
  • Syntax highlighting still works, but editing assistance is essentially gone.

With K2 disabled, all of the above works again.


How JTE’s plugin currently works

I didn’t find anything in the Kotlin plugin migration guide to K2 for third-party plugins

Potentially related YouTrack: KTIJ-32613
If there are newer docs or sample plugins showing K2-friendly language injection, we’d love the links.

Questions for IntelliJ/Kotlin plugin experts

  1. Is MultiHostInjector still the right extension point for injecting Kotlin under K2 if we need:
    • Top-level imports in injected regions
    • Full name resolution/inspections/completion (not just highlighting)
  2. If not, what’s the recommended K2 approach?
    • Should we use a different host mechanism ?
    • Is there a K2-specific way to create a “file-like” injected context rather than a “code fragment”-like context that forbids imports?
  3. Are there analysis APIs or helpers in K2/FIR we should be using to wire symbol resolution and completion for injected Kotlin?
    • Any minimal example plugins we can study that inject Kotlin (or another language) and preserve imports/resolution under K2?
  4. Any interim workarounds to re-enable imports/resolution in injected Kotlin without disabling K2?
    • Even a toggle/flag/registry key for development/testing would be helpful while we work on a proper migration.

Thank you in advance. Even a small code pointer to a “hello world” K2-compatible injection that allows top-level imports would be gold. We’re motivated to get this working for JTE and the broader Kotlin template ecosystem.

3 Likes

This is a bug with imports, and we are working on it. There must be no red code shown in fragments, although we cannot promise the same level of support for Kotlin IDE features such as completion and resolve

Hey @yuriy.artamonov,

thank you for the response! Is there any kind of timeline or ETA that you can share?
I’m blocked in my current project because of this sadly.

Best Regards
Thomas