Only if the submodules are checked out first. The Git book says a plain clone gives you the submodule directories but none of the files inside them. A scan that runs on that clone sees empty folders and reports nothing for them, which looks like a clean result.
What a plain clone contains
According to the Pro Git book, cloning a project with submodules creates the submodule directories, but they are empty until you initialise and update them. Two commands do that, or you can pass the recurse option at clone time, which initialises and updates each submodule, including nested ones. For a clone you already have, the combined update with init does the job, and the book calls the recursive form the foolproof option for nested submodules.
git clone --recurse-submodules <repo-url>
git submodule update --init --recursive
The book also notes that submodules end up checked out at the exact commit the parent repository records, in a detached HEAD state.
In CI
The GitHub checkout action documents a submodules input that defaults to false. Setting it to true checks out top level submodules, and recursive checks out nested ones. If you do not set it, your scan runs without them.
| Setting | What the scan sees |
|---|---|
| Default checkout | Parent repo only, empty submodule folders |
| Submodules true | Top level submodules at the recorded commit |
| Submodules recursive | Nested submodules too |
Should you scan them at all?
That depends on ownership.
- Your own code in another repo. Scan it, either as part of the parent or in its own repository. Avoid doing both without a plan, or findings appear twice.
- Third party code you vendored through a submodule. It ships with your product, so it is your risk. Scan it, and track the commit.
- A test fixture or docs repository. Probably out of scope. Say so.
Submodules also hide a version question. The recorded commit may not match any release tag, so a scanner that matches by version number may not recognise the component. Look for manifest files inside the submodule, since a lockfile gives the scanner something real to read.
Make misses visible
Add a CI step that lists the submodule paths and fails if any is empty. You can ask Git for the configured submodules and compare with the folders on disk.
git submodule status
A leading minus in the status output means the submodule is not initialised. Make that a failure in the scan job.
Related reading
For vendored code that lives directly in the repository, see should you vendor dependencies into your repo.
Safeguard scans repositories and dependencies, so check that your pipeline gives it the files. A quick test on any checked out folder is the free scan at https://gold.safeguard.sh/scan.
Quick check
Why does my scan find nothing in a submodule folder?
The folder is probably empty because submodules were not initialised after cloning.
How do I check out submodules in the GitHub checkout action?
Set the submodules input to true, or to recursive for nested ones. It defaults to false.
Sources
Last reviewed: 19 October 2026.