The “Deploy Debian Repo” workflow (self-hosted runner s1) failed every run at
the Build WASM step:
1
2
3
4
> Task :composeApp:compileDevelopmentExecutableKotlinWasmJs FAILED
e: java.lang.NullPointerException: Cannot invoke
"...IrMangleComputer.getTypeParameterContainers()" because "$this" is null
e: Compiler terminated with internal error
The same command passed on a developer laptop. The per-module compiles
(:shared/:composeApp:compileKotlinWasmJs) were FROM-CACHE; only the
executable-link step (which consumes those cached klibs) crashed.
A corrupt/stale wasm klib in s1’s persistent shared Gradle build cache
(~/.gradle/caches/build-cache-1, org.gradle.caching=true). s1 is a
long-lived self-hosted runner, so GRADLE_USER_HOME persists across runs (and
is shared with other workflows + manual builds). The WASM step has
timeout-minutes: 15; a build killed mid-write (timeout, or a colliding build)
can leave a partial/incompatible klib in the build cache. Every later run then
restores it (FROM-CACHE) and the IR linker NPEs on it. The laptop has a
locally-consistent cache, so it passes.
Confirmed by reproduction: building the failing task on s1 with an isolated,
empty GRADLE_USER_HOME (--gradle-user-home /tmp/... --no-build-cache)
succeeded in 2m51s — proving the source/JDK/RAM are fine and only the cached
artifact was bad. (s1 has JDK 21 available and 125G RAM; not a JDK or OOM issue.)
Added --no-build-cache to every ./gradlew build invocation in the
package-debian job (wasm, server proguard, desktop uber-jar, krill-pi4j and
krill-mcp shadowJars). A release/deploy build must compile fresh rather than
trust a corruptible persistent cache. Note: gradle/actions/setup-gradle’s
cache-disabled would not fix this — on a self-hosted runner the local
~/.gradle/caches persists regardless, and org.gradle.caching=true reads it;
only --no-build-cache on the invocation bypasses it.
On self-hosted runners with a persistent GRADLE_USER_HOME, treat the build
cache as untrusted for release builds — --no-build-cache (or a clean home).
When a Kotlin/Wasm “Internal compiler error” / IrMangleComputer NPE appears
only in CI and only on FROM-CACHE tasks, suspect a corrupt cached klib, not
the source. To clear it manually when the runner is idle:
rm -rf ~/.gradle/caches/build-cache-1. Consider also raising the WASM
timeout-minutes so a slow build isn’t killed mid-cache-write.