Gate tracked ref filter on advanced vulnerability management
What does this MR do and why?
Adds a check for the access_advanced_vulnerability_management ability to the frontend gate that decides whether the "Tracked ref" filter token appears in the vulnerability report's filtered search. Without that check the token renders — and pre-applies a default value — on every project, including instances where the backend cannot accept the argument it sends. The whole vulnerability report then fails to load.
The causal chain:
vulnerabilities_across_contextsshipped asbetawithdefault_enabled: truein !250276 (merged), so the Tracked ref token now renders for every project by default.TrackedRefTokenpre-selects the project's default branch through itsdefaultValues()hook, andfiltered_search.vueturns that into an initial filter value. SotrackedRefIdsis sent on page load, before the user touches the filter.trackedRefIdsmaps tosecurity_project_tracked_context_id, one of theADVANCED_FILTERSinee/app/graphql/resolvers/vulnerability_filterable.rb.- That filter requires the
access_advanced_vulnerability_managementability, which requires advanced search to be configured —Search::Elastic::VulnerabilityIndexHelper.advanced_vulnerability_management_allowed?needs both theelasticsearch_indexingandelasticsearch_searchapplication settings. - On an instance without advanced search,
validate_advanced_vuln_management!raisesRequire advanced vulnerability management to be enabled!, so bothproject.vulnerabilitiesandproject.vulnerabilitySeveritiesCountfail. The user gets an "Error fetching the vulnerability counts" banner, all six severity tiles reading "Something went wrong", an applied "Tracked ref" chip they never chose, and "No vulnerabilities to report".
The fix reuses the existing advancedVulnerabilityManagement computed property in the same component. The REACHABILITY and VALIDITY_CHECK cases in the same switch already gate on it, and the only two filter presets that include TRACKED_REF (DEVELOPMENT_PROJECT and OPERATIONAL_PROJECT) also include those two, so the ability is already required and pushed to the frontend on the affected pages.
This was found through E2E, but it is a user-facing bug: any self-managed instance without advanced search configured hits the same broken report, because the flag defaults on.
Local testing observations
Tested against a local GDK, EE Ultimate license, with the vulnerabilities_across_contexts flag enabled (it is beta / default_enabled: true), on a project with 1,100 vulnerabilities, default branch main, and a default-branch Security::ProjectTrackedContext record. All requests were run as an owner/admin user via GitlabSchema.execute, using the same GraphQL query the report page issues on load:
query($fullPath: ID!, $trackedRefIds: [SecurityProjectTrackedContextID!]) {
project(fullPath: $fullPath) {
vulnerabilities(trackedRefIds: $trackedRefIds, first: 3) { nodes { id } }
vulnerabilitySeveritiesCount(trackedRefIds: $trackedRefIds) { critical high medium low }
}
}| Case | Advanced search | trackedRefIds sent |
Result |
|---|---|---|---|
| A | OFF | Yes | Error: Require advanced vulnerability management to be enabled! (both fields) |
| B | OFF | No | Loads: 3 vulnerabilities, counts critical: 55, low: 1045 |
| C | ON | Yes | Loads: 3 vulnerabilities, counts critical: 55, low: 1045 |
Before / after: on master, case A is what actually happens on page load for any instance without advanced search configured — the report is broken. With this MR the token is not rendered, trackedRefIds is never sent, and the report loads (case B).
- A vs B isolates the cause: the only difference between the two requests is whether
trackedRefIdsis present, and that alone flips the result from erroring to succeeding. - C shows the MR does not regress instances that do have advanced search configured — the tracked-ref filter still works there, and
access_advanced_vulnerability_managementis exactly what distinguishes the working case (C) from the broken one (A).
Added a Jest test asserting the token is absent when accessAdvancedVulnerabilityManagement is false; confirmed it fails on master (token present) and passes with the fix. The full spec file passes (25 tests), and the wider filtered_search plus vulnerability_report suites pass (39 suites, 1,573 tests).
The advanced-search settings were restored to their original values (both enabled) after testing.
Screenshots or screen recordings
Captured locally in Chrome (via Capybara) on a project with one SAST vulnerability and a default-branch Security::ProjectTrackedContext. Advanced search is unconfigured, which is the RSpec default — so this is the exact scenario the bug affects, with no settings tampering needed.
Before (master) |
After (this MR) |
|---|---|
![]() |
![]() |
Before: the counts error banner, all six severity tiles reading "Something went wrong", Development vulnerabilities 0, and no rows. After: real counts (High 1), no banner, and the vulnerability listed.
Assertions extracted from the saved DOM of each run, rather than read off the images:
| Check | Before (master) |
After (this MR) |
|---|---|---|
Tracked ref filter applied |
present | absent |
| "Error fetching the vulnerability counts" banner | present | absent |
| Severity tiles reading "Something went wrong" | present | absent |
| "No vulnerabilities to report" | present | absent |
| Vulnerability row rendered | absent | present |
| "Limited experience available" callout | present | present |
The limited-experience callout is expected in both: it is the legitimate notice that advanced search is not configured, and this MR does not suppress it. Only the pre-applied filter and the resulting query failure go away.
How to set up and validate locally
-
Prerequisites: a GDK with an EE Ultimate license, a project with some vulnerabilities, and a default-branch
Security::ProjectTrackedContextrecord for that project. The report page only pre-applies theTracked reffilter when one exists —EE::ProjectsHelperprovidesdefault_branch_contextfromSecurity::ProjectTrackedContext.find_default_branch_context. -
Simulate an instance without advanced search. In the Rails console, disable both application settings and expire the settings cache:
s = ApplicationSetting.current s.elasticsearch_indexing = false s.elasticsearch_search = false s.save!(validate: false) Gitlab::CurrentSettings.expire_current_application_settingsNote:
elasticsearch_indexingandelasticsearch_searchlive in theelasticsearchJSONB column onapplication_settings, soupdate_columnsfails withPG::UndefinedColumn— use the attribute writers as shown. If your GDK normally has advanced search enabled, restore both settings totruethe same way when you are done. -
Confirm the precondition took effect:
Search::Elastic::VulnerabilityIndexHelper.advanced_vulnerability_management_allowed?should returnfalse. -
On
master, open the project's Secure → Vulnerability report. Expect the broken state: an "Error fetching the vulnerability counts" banner, severity tiles reading "Something went wrong", an appliedTracked refchip the user never selected, and "No vulnerabilities to report". -
Optionally reproduce at the API layer instead of the UI, by running the same GraphQL query with and without
trackedRefIds:query($fullPath: ID!, $trackedRefIds: [SecurityProjectTrackedContextID!]) { project(fullPath: $fullPath) { vulnerabilities(trackedRefIds: $trackedRefIds, first: 3) { nodes { id } } vulnerabilitySeveritiesCount(trackedRefIds: $trackedRefIds) { critical high medium low } } }With
trackedRefIdsset it errors; without it, it succeeds. -
Check out this branch, reload frontend assets, and reload the report. Expect the
Tracked reftoken to be gone and the report to load normally, with counts and rows. -
Run the Jest spec:
yarn jest ee/spec/frontend/security_dashboard/components/shared/filtered_search/vulnerability_report_filtered_search_spec.js
References
- Incident: gitlab-org/quality/analytics/ci-health-incidents#1169 (closed)
- Root cause analysis note: gitlab-org/quality/analytics/ci-health-incidents#1169 (comment 3704126414)
- Causing MR: !250276 (merged)
- Feature flag rollout issue: #578047
Five sibling security-risk-management vulnerability report E2E specs are still fast-quarantined for this same root cause. Fast quarantines are cleared automatically every Sunday, so they should be re-checked once this merges.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

