Code scanning as a developer tool
GitHub's code scanning is usually discussed as a security measure, but the same CodeQL engine behind it can act as a code-quality safeguard. GitHub has started using custom CodeQL queries internally to catch common coding mistakes before they become production incidents. The queries described below are experimental and not part of the standard suites, but they are available for any team to adopt.
Keep defer out of loops
In Go, defer schedules a function to run when the enclosing function returns, which makes it convenient for cleanup—closing file handles, finishing transactions, and similar tasks. However, when refactoring existing code, it is easy to accidentally place a defer inside a loop. Because the cleanup will still wait until the end of the entire function rather than the end of each iteration, this mistake can leak resources in long-running code.
A four-line CodeQL query detects that exact pattern:
Adopting this query had a side benefit: another team at GitHub, having been burned by a defer-in-loop memory leak previously, decided to turn on code scanning for their repository. The scan quickly surfaced a similar latent problem.
Checking the errors you can't see
Some Go libraries deviate from idiomatic error handling. GORM, an object-relational mapper, uses a chainable API where errors are stored on the result object rather than returned. Calls like db.Where("name = ?", "jinzhu").First(&user) are easy to write without inspecting the Error field afterward.
GitHub now runs a custom query that flags GORM calls that do not check the corresponding Error field, surfacing the issue directly in pull requests. A related query for checking pointer-returning functions is included in the security-and-quality query suite as MissingErrorCheck.
Finding N+1 performance traps
Database round-trips inside loops, the so-called N+1 query problem, can degrade application performance as input sizes grow. GitHub built a query that scans for any GORM method invocation that results in an actual database query and then flags calls executed inside loops, failing CI when found.
A key benefit of the CodeQL approach is that the analysis is not limited to queries that appear literally inside a loop body. If a database call sits in a function that is invoked—directly or through several layers of calls—from a loop, it is still reported.
Running the developer-happiness queries
These queries are experimental, so they are not included in the standard CodeQL suites. To use them, create a query suite file at .github/codeql/go-developer-happiness.qls in the repository you want to analyze:
- import: codeql-suites/go-developer-happiness.qls
from: codeql-go
Then modify the "Initialize CodeQL" step in your CodeQL workflow configuration:
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: go
queries: ./.github/codeql/go-developer-happiness.qls
Full configuration guidance is available in the documentation for running additional queries in GitHub code scanning.
Writing your own
If your codebase has recurring patterns that trip up developers, similar custom queries can be built. The CodeQL documentation and discussion forums cover both query authoring and contributing queries back to the community via the codeql repository.



