Use the bazel mod command. The explain subcommand shows every place a module appears in the graph and which modules directly depend on it. The all_paths and path subcommands show how the root reaches it. Together they answer why a risky module is present.
The questions you will ask
When an advisory lands, you need two answers: are we using this module, and who brought it in? In a Bazel module graph the mod command is built for exactly that. Bazel's documentation describes it as a way to visualize the external dependency graph, find out why a module or version is present, and view extensions.
The subcommands
| Subcommand | What it shows |
|---|---|
| graph | The full dependency graph from the root, expanding only when needed |
| all_paths | Every dependency path from chosen modules to chosen targets |
| path | The same idea, but only one path |
| explain | Every place the module appears, with the modules that directly depend on it |
| deps | Resolves the graph and refreshes the lockfile |
A typical session looks like this.
bazel mod explain some_module
bazel mod all_paths some_module
bazel mod graph
A workflow for an advisory
- Run explain for the affected module name. Note the version and direct dependents.
- Run all_paths to see whether the route comes from your own declared dependency or from a deep transitive one.
- If the version is lower than your direct entry would imply, remember the selection rule: Bazel picks the highest version any dependent requests. A lower version in the graph before resolution gets raised.
- Decide on the fix. Raise your direct dependency, raise the minimum in the module that requests it, or use a single version override at the root.
- Re-run explain to confirm the new version, and commit the lockfile change.
Pitfalls
- Overrides in a dependency's own module file are ignored. Only the root module's overrides apply.
- Repositories that are not modules, such as ones defined directly with a repository rule, do not appear as modules, so check those separately.
- The module graph is a resolution graph. It does not list packages from other ecosystems pulled in by extensions, so supplement it with an inventory that does.
Turning the answer into a record
Save the explain output in the incident ticket. It shows version, dependents and path, and it is the evidence for "affected" or "not affected" later.
Where Safeguard fits
Safeguard can inventory the dependencies your repository declares through SBOM and dependency scanning, and reachability analysis helps you decide which findings matter first. You can try a free scan on a repository to see what it finds. Check coverage for your specific build files before relying on it.
Try it yourself
In the demo, search the inventory for a component and follow how it connects back to the project, then compare that to what explain gives you for a module.
Click through it at your own pace, or open it full screen.
Quick check
Does explain show packages from other ecosystems?
It shows Bazel modules in the resolved graph. Packages generated by extensions may need a separate inventory.
Which version does Bazel select when two are requested?
The highest version requested by any dependent, using Minimal Version Selection. It does not jump to a newer version that nobody asked for.
Sources
Last reviewed: 19 October 2026.