A Patch Release With a Major Version Inside
CodeQL 2.26.1 was announced as accuracy and framework coverage. One of the packs it ships removed a feature and went to 12.0.0.
CodeQL 2.26.1 was announced as improved analysis accuracy and wider framework coverage. That framing predicts your alert count goes down. Read the pack changelogs behind the release and it moves both ways — and one of the packs removed a feature.
What shipped, and when
CodeQL 2.26.1. The CLI changelog dates the release to 15 July 2026, and the changelog index on the same site dates 2.26.0 to 8 July 2026. GitHub's changelog post announcing 2.26.1 is dated 29 July 2026 — fourteen days after the release date the CLI changelog gives. The announcement says the release deploys automatically for GitHub.com users, will be included in a future GitHub Enterprise Server version, and can be upgraded manually on older Enterprise Server versions. Neither page states when GitHub.com began serving it, so the fourteen days is a documentation gap, not a rollout claim.
Scale, from the CLI changelog: the Default suite carries 497 security queries covering 170 CWEs, and the Extended suite adds 131 queries covering 32 more.
What the announcement left out
The library pack changelogs in github/codeql name two languages the announcement does not mention at all.
codeql/python-all 7.2.1 changes Flask app resolution: Flask::FlaskApp::instance() now also returns instances of subclasses defined in the source tree, which were previously filtered out, and Flask::FlaskApp::classRef() is deprecated in favor of subclassRef(). Any Flask codebase that subclasses Flask gets a different source set.
codeql/csharp-all 7.1.0 changes how build-mode: none fetches NuGet dependencies: sources are supplied through a -Source flag instead of by moving or creating nuget.config files in the checked-out repository, private registries are used when configured, and only reachable feeds are used when feed checking is on. That is a change to how dependencies get fetched, and no query ID is attached to it — nothing in an alert diff will point at it.
Then the one that matters most. codeql/cpp-all went to 12.0.0 — a major version — on a breaking change: support for using variables as sources and sinks in models-as-data is removed, and the changelog directs users of that feature to rewrite them as QL definitions. The announcement mentions the same release's deprecation — flow summaries moving to fully qualified field names such as MyNamespace::MyStruct::myField, with a twelve-month window on the unqualified form — but not the removal. The pack changelog itself gives no timeline, only a future release; the twelve-month figure exists in the announcement.
The current C/C++ models-as-data guide describes rows keyed to a callable across nine columns, with sources and sinks written as argument or return-value specifications. It does not document variables as sources or sinks anywhere. The docs already read as though the feature never existed, while the extension files in your repository still contain it.
Alert counts move in both directions
Up:
java/ssrfnow treats the first argument of Spring WebFlux'sWebClient.UriSpec.urias a request forgery sink. The pack changelog says this may increase alerts.go/log-injectionandgo/clear-text-loggingwiden through newlog/slogmodels. That package has been in the Go standard library since 1.21; the modeled surface includesLogger.With, which returns a logger carrying the given attributes into each output operation, andLogger.WithGroup, which qualifies the keys of attributes added afterward.js/missing-origin-checkgains Angular@HostListenersources.
Down:
java/path-injectionnow treats@javax.validation.constraints.Patternas a sanitizer.rust/hard-coded-cryptographic-valuetreats arithmetic, bitwise, and string-append operations as barriers, cutting false positives where constants combine with variable input.
Sideways: the C/C++ uncontrolled-process-operation query gained CWE-073 and CWE-078 tags, and the C# assembly-path-injection query gained CWE-073. No detection changed. If you filter alerts or build compliance reports by CWE, findings you already had will surface under categories they did not surface under before.
The claim: re-scan an unchanged commit on 2.26.1 and the alert set changes in both directions across Java, Go, JavaScript, and Rust. What would show it wrong: a repository in those languages, re-scanned with no source change, producing an identical alert set — which would mean these models and barriers do not touch real code, and pinning is pure overhead.
Where the new Angular coverage stops
An announcement says coverage was added. The query library says under what conditions. The predicate in javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll requires all three of: a decorator resolving to the HostListener member of @angular/core; a first argument with a provable string value matching one of exactly two event names, the window and document forms of message; and the event arriving as the method's first parameter.
Angular's own reference lists three global target prefixes that can precede an event name — document:, window:, and body:. Two of the three are modeled. The same page tells readers to prefer the host property and describes @HostListener as existing for backwards compatibility. The predicate has no clause for the host property form. A component written to current Angular guidance receives none of this new coverage.
What to do this week
Pin the bundle instead of inheriting it. github/codeql-action/init takes a tools input accepting a local bundle tarball path, the URL of a bundle release asset, linked for the tools shipped with the action, or nightly. Left unset, the action resolves tools on its own — which is how an accuracy change lands on a day you did not pick.
- uses: github/codeql-action/init
with:
languages: java-kotlin
tools: <url of a CodeQL bundle release asset>
Then, in order:
grep -rl 'pack: codeql/cpp-all' --include='*.yml' .— every C/C++ data extension file is a candidate for the removed variable sources and sinks.- Re-scan one unchanged commit on the old and the new bundle, and diff the alert sets. Do it per language; the direction differs by language.
- If a required check fails on new alerts, expect it to fail on code nobody touched. Decide now whether that blocks merges or files tickets.
- If CWE filters feed a compliance artifact, re-run it before someone else notices the counts moved.
Verdict
Adopt, and pin. Every model and barrier change here is specific and traceable to a named query. The cost is that a patch-numbered release carries a major-version removal in one pack and unannounced changes in two more, so the CLI version string is not a reliable signal of blast radius. The pack changelogs are.
This is the ordinary shape of the last-mile problem we keep coming back to: the gate you built to make quality measurable is itself a measurement instrument, and this week it got recalibrated without a version number that said so. An eval harness whose version you do not control is not a harness.
Sources
- CodeQL 2.26.1 improves analysis accuracy and framework coverage
- CodeQL CLI 2.26.1 changelog
- CodeQL CLI changelog index
- Customizing library models for C and C++
- github/codeql — cpp/ql/lib/CHANGELOG.md
- github/codeql — javascript/ql/lib/semmle/javascript/security/dataflow/DOM.qll
- github/codeql-action — init/action.yml
- Go standard library: log/slog
- Angular API reference: HostListener
Turn this into a plan for your team.
One week, fixed fee: a working session with your team, a prioritized use-case backlog, and an ROI model for the opportunities worth chasing.