CodeQL 2.26.1 changed C++ models-as-data so field names are written in fully qualified form. GitHub says support for the old unqualified form is planned for removal after a 12-month transition period.
This matters to teams that maintain custom models for internal libraries or frameworks. A model can make static analysis understand a source, sink, sanitizer, or flow step that the standard library does not know. If a custom row stops matching, security coverage can disappear without an application compile error.
Quick answer
Inventory custom C++ model packs, update field references to their fully qualified names, run before-and-after analysis on a fixed commit, and keep a small test case that depends on each important model. Do not wait until the compatibility form is removed.
# Conceptual example
# Before: token
# After: company::auth::Request::token
Use the exact model schema and generated output for your CodeQL version; the representation differs by model kind. The important migration is from an ambiguous short field name to the complete declaring scope.
Why qualification improves accuracy
Large C++ programs frequently contain fields with the same short name: data, value, token, path, or buffer. An unqualified model can be ambiguous across namespaces, nested classes, inheritance, and generated code.
A fully qualified name identifies the intended declaration. That makes models easier to review and helps prevent one internal library model from matching unrelated code.
The compatibility period exists because custom packs are outside GitHub’s repository. CodeQL cannot update them automatically when it updates the standard query bundle.
Find custom models in your organization
Search security tooling repositories, application repositories, shared CI actions, and published CodeQL packs. Look for model extension YAML, data extensions, query packs, and scripts that generate models.
find . -type f \( -name '*.yml' -o -name '*.yaml' -o -name 'qlpack.yml' \) \
-print
rg -n 'extensions:|dataExtensions:|sourceModel|sinkModel|summaryModel' .
Record the pack name, owner, consuming repositories, CodeQL version range, and the security behavior each custom model is expected to create.
Migrate with an observable test
Choose a fixed application commit and run the current pack before editing. Save the SARIF result and database logs. Update a small group of field names, rebuild the pack, and analyze the same commit again.
Compare:
- query result count by rule;
- modeled source and sink locations;
- extraction and model-extension warnings;
- analysis time;
- one known-positive flow for each critical model.
A lower result count is not automatically an improvement. It may mean better precision, or it may mean a model stopped matching.
Build a model contract fixture
Create a tiny C++ sample that imports the internal API, moves tainted input through the modeled field, and reaches a safe test sink. Keep it beside the model pack and run it during upgrades.
The fixture does not need to reproduce the entire application. It should fail clearly when the field model is absent and pass when the model loads. Add a negative case using another class with the same short field name; qualification should prevent an accidental match.
Avoid common migration mistakes
Do not perform a blind text replacement of every field token. Overloaded types, templates, aliases, generated declarations, and nested scopes need the name CodeQL resolves, not necessarily the spelling a developer expects from one source line.
Do not mix a query-bundle upgrade, compiler upgrade, and model rewrite in the same baseline comparison. Change one analysis layer at a time so result differences remain explainable.
Finally, do not delete compatibility comments immediately. Record the previous form, the version that introduced the new form, and the date the migration was verified. That history helps the next maintainer understand why the qualification is required.
Run the migrated pack in the same CodeQL CLI version used by production CI. A successful local compile on a newer CLI does not prove the deployed scanner can load the schema. Pin the tested pack and CLI versions together until rollout is complete.
Primary sources
- CodeQL 2.26.1 analysis update
- CodeQL model packs documentation
- CodeQL model editor documentation
- CodeQL C++ query help
Treat custom models as security code with a contract. Fully qualify the intended fields, compare analysis on an unchanged commit, and keep a known-positive fixture so a future CodeQL upgrade cannot silently remove the coverage you meant to add.
Discussion
What would you try, change, or challenge after reading this guide? Specific results and errors help the next reader.
Comments will load as you reach this section.