Summary
kosli attest sonar --sonar-project-key cannot find an analysis on any branch other than the project's main branch. This is the same defect as #861, in the sibling code path that #861 did not cover.
#861 fixed GetProjectAnalysisFromAnalysisID, which now forwards the branch (internal/sonar/sonar.go:430). GetProjectAnalysisFromRevision still calls:
sonarURL(sonarResults.ServerUrl, "api/project_analyses/search",
url.Values{"project": {project.Key}})with no branch parameter. SonarQube defaults that endpoint to the main branch, so the search returns nothing and the user gets:
analysis for revision <sha> of project <key> not found. Check the revision is correct.
even though the analysis exists.
Why the #861 fix does not cover this path
sonarResults.Branch is only ever populated from a Compute Engine task response (sonar.go:368-374 and 601-607). The revision path has no task — it is searching for the analysis by revision — so Branch is always nil there and there is nothing to forward. The CLI cannot infer the branch on this path, so it has to be told.
Evidence from a live customer instance
api/project_branches/list:
{"branches":[
{"name":"master","isMain":true,"status":{}},
{"name":"release/uat","isMain":false,"analysisDate":"2026-08-20T11:09:48+0400"}
]}master has never been analysed. Unscoped, the search is correctly empty:
{"paging":{"total":0},"analyses":[]}Scoped to the branch, the analysis is there with the exact revision the CLI was looking for:
{"analyses":[{"key":"AaAeAfTdP27JeOuKOycd","date":"2026-08-20T11:09:48+0400",
"revision":"8700f236fe2fd6c3e2dc5bf33c7e5f3aa8fd3dee"}]}Impact
Any team that scans a branch rather than the main branch, which in CI is the common case. It presents as a permissions or token problem, because SonarQube returns an empty result rather than an error: at this customer it cost several days of chasing token types and Browse permissions before the real cause was found. Their token and permissions were correct throughout.
Proposed fix
Add a --sonar-branch flag, mirroring the existing --pull-request, and forward it to api/project_analyses/search when set. Behaviour is unchanged when it is not set, so this is backwards compatible.
Workaround in use
The customer's pipeline currently lists branches and matches the revision itself, then reads the gate by analysisId, attesting the result with kosli attest generic. That loses the native sonar attestation type, so it should be removed once this is fixed.
Summary
kosli attest sonar --sonar-project-keycannot find an analysis on any branch other than the project's main branch. This is the same defect as #861, in the sibling code path that #861 did not cover.#861 fixed
GetProjectAnalysisFromAnalysisID, which now forwards the branch (internal/sonar/sonar.go:430).GetProjectAnalysisFromRevisionstill calls:with no
branchparameter. SonarQube defaults that endpoint to the main branch, so the search returns nothing and the user gets:even though the analysis exists.
Why the #861 fix does not cover this path
sonarResults.Branchis only ever populated from a Compute Engine task response (sonar.go:368-374and601-607). The revision path has no task — it is searching for the analysis by revision — soBranchis alwaysnilthere and there is nothing to forward. The CLI cannot infer the branch on this path, so it has to be told.Evidence from a live customer instance
api/project_branches/list:{"branches":[ {"name":"master","isMain":true,"status":{}}, {"name":"release/uat","isMain":false,"analysisDate":"2026-08-20T11:09:48+0400"} ]}masterhas never been analysed. Unscoped, the search is correctly empty:{"paging":{"total":0},"analyses":[]}Scoped to the branch, the analysis is there with the exact revision the CLI was looking for:
{"analyses":[{"key":"AaAeAfTdP27JeOuKOycd","date":"2026-08-20T11:09:48+0400", "revision":"8700f236fe2fd6c3e2dc5bf33c7e5f3aa8fd3dee"}]}Impact
Any team that scans a branch rather than the main branch, which in CI is the common case. It presents as a permissions or token problem, because SonarQube returns an empty result rather than an error: at this customer it cost several days of chasing token types and Browse permissions before the real cause was found. Their token and permissions were correct throughout.
Proposed fix
Add a
--sonar-branchflag, mirroring the existing--pull-request, and forward it toapi/project_analyses/searchwhen set. Behaviour is unchanged when it is not set, so this is backwards compatible.Workaround in use
The customer's pipeline currently lists branches and matches the revision itself, then reads the gate by
analysisId, attesting the result withkosli attest generic. That loses the nativesonarattestation type, so it should be removed once this is fixed.