Safeguard
Developer Tools•

Scanning a large monorepo with the Safeguard CLI without timeouts

When a monorepo scan runs out of memory or times out, scan package folders separately, check lock files, and use transitive resolution deliberately.

Safeguard Security Team
3 min read

If a monorepo scan with the Safeguard CLI times out or runs out of memory, scan each package directory separately instead of the whole tree. Make sure lock files exist so the SBOM is complete, and leave transitive resolution off until you need it. The troubleshooting docs recommend this approach.

What goes wrong at scale

Two failure modes show up on big repositories:

  • Out of memory. The troubleshooting page lists it for monorepos too large for one scan, and recommends scanning each package directory on its own.
  • Timeouts. Large scans, or transitive resolution on a deep tree, take longer than a pipeline allows.

A third problem looks like success: a scan that finishes quickly with few results, because manifests were not found or dependencies were not installed.

Split by package

Run the scan against one folder at a time, and give each its own output folder:

for d in packages/*/ ; do
  name=$(basename "$d")
  safeguard scan --dir "$d" --output "out/$name" || echo "failed: $name" >&2
done

Two practical benefits: a failure points at one package, and you can run folders in parallel on separate jobs. Keep the exit code per folder, and treat a code of 2 as a failure, since it means vulnerability matching did not run.

Fix the inputs first

An incomplete SBOM is usually an input problem:

  • Install dependencies before scanning, for example with your package manager's install step.
  • Commit lock files. Without them the scanner can only see version ranges.
  • Pass the directory explicitly, so you are not scanning the wrong working folder.

If the message says no dependencies were found, check those three before anything else.

Transitive resolution is a choice

The scan has an option to resolve transitive dependencies, and the docs say it is off unless you ask for it. It adds depth and time. Related options control how many requests run at once and how deep to go.

A reasonable approach: leave it off for pull request checks, turn it on for nightly or release scans, and compare the counts so you know what it adds. If a run times out with it on, scan a subfolder or lower the depth.

Tell the scan what is private

For repositories with internal packages, the namespace options let you say which names are yours, and which belong to third party vendors. That helps the report separate your own code from outside code, and avoids sending internal names to be looked up as if they were public.

Make it fast enough for CI

  • Scan only the packages changed in the pull request, using your CI system's path filters.
  • Run a full scan nightly.
  • Cache the scanner tools and databases between runs where your system allows it.
  • Set a timeout slightly above your normal run time, so a hang fails fast.

Quick check

My scan finished instantly with no results. Is the code clean?

Probably not. Check that dependencies are installed, lock files are present and you are scanning the right folder. An empty inventory means the scanner found nothing to read.

Should I always resolve transitive dependencies?

Not on every run. It is off by default and slows large scans. Use it on nightly or release scans and compare the results.

Safeguard also offers a free scan at gold.safeguard.sh/scan for smaller public projects.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.