Skip to content

Java/Kotlin: regression in 2.24.1+ — analysis time 12 min → 3-5 hours (or hang), bisected to CodeQL CLI version #21874

@dustinlewis

Description

@dustinlewis

Summary

CodeQL Java/Kotlin analysis on a large multi-module Android Kotlin codebase regressed sharply between CodeQL CLI 2.24.0 and 2.24.1. The same workflow, codebase, runner, and query suite that completed in ~12-15 minutes on 2.24.0 now takes 3-5 hours when it converges at all (~37.5% success rate); 60% of runs hang and hit the GitHub-hosted runner 6-hour cap.

The regression is reproducible by version bisection — pinning the CLI back to 2.24.0 via the tools: parameter restores the historical ~12-minute behavior with 100% convergence on the same codebase and configuration.

Bisection result

Three parallel runs with tools: codeql-bundle-v2.24.0:

Run Duration Conclusion
1 12m 56s Success
2 15m 29s Success
3 13m 32s Success

Versus the same workflow without the pin (uses current @v4 bundle, CodeQL CLI 2.25.4):

Suite Runs Successes Failures Success duration Failure
security-and-quality 5 2 (40%) 3 (60%) 3h12m, 5h15m 6h cap
security-extended 3 1 (33%) 2 (67%) 4h52m 6h cap
Combined post-2.24.1 8 3 (37.5%) 5 (62.5%) 3-5 hours 6h cap

Only the CLI version differs between the pinned-2.24.0 set and the unpinned set. Same codebase, same workflow, same runner, same suite, sometimes within minutes of each other.

Historical context

Pre-regression, this scan ran nightly for ~3 months with 100% green:

Window Outcome
Nov 2025 (30 runs) All green
Dec 2025 (31 runs) All green
Jan 2026 (31 runs) All green
Feb 1-6, 2026 (6 runs) All green
Feb 7, 2026 onward (~150 runs) Nearly all fail at the 6h cap

Historical successful run durations (sampled across the green period): 12-18 minutes consistently.

Feb 7, 2026 is the day after github/codeql-action v4.32.2 shipped (Feb 5, 2026), which bundled CodeQL CLI 2.24.1.

Suspected cause

Per the 2.24.1 changelog:

The SummarizedCallable.propagatesFlow predicate has been extended with columns Provenance p and boolean isExact. The predicates SummarizedCallable.hasProvenance and SummarizedCallable.hasExactModel have been removed as a consequence. This change affects C/C++, C#, Golang, Java/Kotlin, JavaScript/TypeScript, Python, Ruby, Swift, and Rust libraries.

SummarizedCallable.propagatesFlow is in the same data-flow framework where our hung runs' evaluator logs show repeated 13.5 GB tuple-table evictions on TypeFlow<Location, TypeFlow::Input>::UnivFlow::ForAll<...> predicates. The eviction itself is normal memory management — but on 2.25.x it sometimes thrashes indefinitely; on 2.24.0 it doesn't trigger or recovers quickly.

Environment

  • CodeQL CLI: 2.24.0 (green) vs. 2.25.4 (regressed) — bisected, regression starts in 2.24.1
  • codeql-action: @v4 (unchanged across both)
  • Build mode: manual (Gradle build, ./gradlew --no-daemon --no-build-cache clean assembleDebug)
  • Runner: Linux 16-core (GHAS large runner), 64 GB RAM
  • Codebase: ~22 Gradle modules, Kotlin-only source (Java only in compiled deps: Android SDK, AndroidX, Compose, Retrofit, OkHttp). Extracted database has 3,645,995 expressions in TypeFlow::FlowStepsInput::TExpr.

Symptom on regressed versions

After the build phase (~12 min consistently), CodeQL init runs (~1 min), first ~146 syntactic queries finish (~5 min). Then:

Created relation ListOfConstantsSanitizer::FlowNode.asExpr/0#dispred#... with 3,640,831 rows
Starting to evaluate predicate TypeFlowImpl::TypeFlow<Location::Location,TypeFlow::Input>::UnivFlow::ForAll<FlowScc,...>::flowJoin/3 (iteration 1)
... delta sizes grow across iterations 1-3 ...
Pausing evaluation to evict 795.21MiB ARRAYS at sequence stamp o+0
Unpausing evaluation: 13.51GiB forgotten: 13.51GiB UNREACHABLE
Starting to evaluate predicate _TypeFlowImpl::TypeFlow<...>::antijoin_rhs#1/4@i3 (iteration 3)
... silence for the remaining 5+ hours ...
Job killed at 6-hour cap

The eviction happens within ~14 seconds of TypeFlow<Location, Input> starting on every regressed run. Sometimes the evaluator continues past it and converges in 3-5 hours; sometimes it never produces another Evaluation done event.

Workaround

Pinning to 2.24.0 via tools: restores reliable nightly scanning. The cost is being frozen on the Jan 2026 QL pack (no new queries, no Kotlin 2.3+ support) until the regression is fixed.

Related

  • Java CodeQL hangs for hazelcast repository #10765 (hazelcast, Oct 2022, acknowledged): similar Java taint-tracking hang pattern. Their workaround (per-query exclusion) doesn't help us because the trigger is in the shared framework, not in any specific query.
  • codeql-action#2378: reports of Java/Kotlin analysis taking 8× build time on large codebases. May be the same regression.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions