Skip to content

fix: stop the recurring CodeQL OutOfMemoryError - #1859

Merged
larsgrefer merged 2 commits into
mainfrom
fix/codeql-kotlin-daemon-heap
Sep 7, 2026
Merged

fix: stop the recurring CodeQL OutOfMemoryError#1859
larsgrefer merged 2 commits into
mainfrom
fix/codeql-kotlin-daemon-heap

Conversation

@Frisch12

@Frisch12 Frisch12 commented Sep 4, 2026

Copy link
Copy Markdown
Member

Problem

Analyze (java-kotlin) fails intermittently, most recently on main in
run 33512523694
after 1h20m, and on 2026-08-31 in
run 33368076297.
Same task both times:

> Task :quicktype-plugin:compileTestKotlin FAILED
e: java.lang.OutOfMemoryError: Java heap space
> Not enough memory to run compilation. Try to increase it via 'gradle.properties':
  kotlin.daemon.jvmargs=-Xmx<size>

Since the job is a required status check, every occurrence blocks merges.

Root cause

Neither org.gradle.jvmargs nor kotlin.daemon.jvmargs was set anywhere.
Gradle's daemon therefore defaulted to -Xmx512m, and the Kotlin daemon
inherits -Xmx from it.
That is not enough for the Kotlin compiler to initialise, even for the ~450
lines of Kotlin in this repository.

It looked flaky because it is really a cache-hit/cache-miss difference: the
regular CI restores ~/.gradle via setup-gradle, so with
org.gradle.caching=true the compile tasks come from the build cache and never
run. CodeQL builds uncached and hits the ceiling every time.

Changes

  • gradle.properties (root and examples/) — set org.gradle.jvmargs and
    kotlin.daemon.jvmargs. Fixing it here rather than in one workflow keeps it
    true for CI on a cache miss and for local builds too.

  • codeql.ymlbuild-mode: autobuildmanual with an explicit
    ./gradlew testClasses --no-daemon --no-build-cache -S and a pinned JDK 17
    (the project toolchain; settings.gradle has no toolchain resolver, so Gradle
    cannot provision one itself).

    --no-build-cache is deliberate and load-bearing: a compile task served from
    the cache invokes no compiler, the tracer sees nothing, and CodeQL would
    report a green run over an empty database. GitHub names Gradle caching as
    a cause of "No source code was seen during the build".
    For the same reason setup-gradle is intentionally not used here.

    The task list is what autobuild already compiled, so the scanned scope is
    unchanged.

  • Timeout for java-kotlin from 360 to 60 minutes. A healthy run takes ~7.

How to verify

Beyond the checks going green, the analysis must not come back empty:

gh api "/repos/freefair/gradle-plugins/code-scanning/analyses?per_page=5" \
  --jq '.[] | {created_at, ref, results_count, rules_count}'

A healthy analysis on main reports rules_count: 240 / results_count: 54.
The failed run uploaded 0 / 0. If this PR's analysis does not report ~240
rules, the build mode is misconfigured and this should not be merged.

Locally ./gradlew assemble and ./gradlew check both pass with the new
settings.

Neither org.gradle.jvmargs nor kotlin.daemon.jvmargs was set, so the
Gradle daemon ran with its 512m default and the Kotlin daemon inherited
that -Xmx. That is not enough for the Kotlin compiler to initialise, even
though this repository holds only ~450 lines of Kotlin.

The regular CI never noticed: setup-gradle restores ~/.gradle, so with
org.gradle.caching=true the compile tasks came from the build cache and
never ran. CodeQL builds uncached and hit the ceiling instead, failing
:quicktype-plugin:compileTestKotlin with OutOfMemoryError after burning
well over an hour in GC thrashing.

Raising the heap in gradle.properties rather than in one workflow keeps
it true for every caller -- CI on a cache miss and local builds included.

Claude-Session: https://claude.ai/code/session_01KoRfB2M6kb2Ci8npcANvUF
Autobuild picked the JDK, the tasks and the Gradle flags on its own, and
its failure surfaced as "We were unable to automatically build your code"
rather than as the compiler error underneath. Spelling the build out
removes that indirection and pins the parts that matter.

--no-build-cache is the load-bearing flag: org.gradle.caching=true would
let compile tasks come from the cache, no compiler would run, and the
tracer would produce an empty database behind a green check. GitHub names
Gradle caching as a cause of "No source code was seen during the build".

The task list stays what autobuild used, so the scanned scope does not
change. The timeout drops from 360 to 60 minutes; a healthy run takes
seven, and the failing one was allowed to spin for eighty.

Claude-Session: https://claude.ai/code/session_01KoRfB2M6kb2Ci8npcANvUF
@larsgrefer
larsgrefer merged commit 696b9a3 into main Sep 7, 2026
19 checks passed
@larsgrefer
larsgrefer deleted the fix/codeql-kotlin-daemon-heap branch September 7, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants