Scan results can change overnight because the advisory data behind the scanner changed, not your code. New advisories get published, existing ones are edited with new ranges or severities, and some are withdrawn. To find the cause, compare the two reports by advisory ID and look at that record's modified time.
Your code is only half the input
A dependency scan joins two things: the list of components in your build, and a database of advisories. Change either side and the output changes. Overnight, the usual change is on the database side.
What can change in a record:
- A new advisory is published for a package you already use.
- An existing record gets a corrected version range, so a version that looked safe is now affected, or the reverse.
- A severity is added to a record that had none, or revised.
- A record is withdrawn.
- Two records are linked as aliases, which can merge what looked like two findings into one.
The OSV schema makes this explicit. Every record has an id and a modified timestamp in UTC, and if two entries claim the same ID, the one with the later modification time is authoritative. A published time is optional, and a withdrawn time, when present, says the entry should be treated as withdrawn. If that field is missing, the entry has not been withdrawn.
A diagnosis routine
- Export both reports, yesterday's and today's, in a format with identifiers. JSON or SARIF is better than a screenshot.
- Compare the sets of advisory IDs. Note which are new, which are gone and which remain.
- For new IDs, look up the record and read its published and modified times. A record published yesterday explains a new finding.
- For IDs that disappeared, check for a withdrawn time. Also check whether another record now lists the first as an alias.
- For IDs that stayed but changed severity or affected status, compare the old and new range and the severity entries.
- If nothing in the data explains it, check the build side: a lockfile change, a base image refresh or a floating version resolved to something new.
Pin the evidence
The cheapest fix for confusion is to store two things with every scan: the list of components found and the time and version of the advisory data used. Without them, "it was clean yesterday" cannot be tested.
Some practical habits.
- Keep scan outputs as build artifacts.
- Record the scanner version and the data timestamp in the report header if the tool offers it.
- Tag a finding with its first-seen date in your tracker, so ageing does not reset when the scan reruns.
What a changed result is not
It is not necessarily a regression. A finding that "appeared" may have been in your software the whole time and simply became known. That is the system working. Treat it as newly discovered, not newly introduced, and look at when the vulnerable version entered your code to decide whether any past releases were also affected.
A finding that "disappeared" deserves a second look too. Confirm it was fixed or withdrawn for a documented reason, not hidden by a data outage or a scanner failure.
Set expectations with your team
Tell developers that results can move without commits. A short note in your contributing guide helps: scans run against live advisory data, so a clean pull request can fail a rerun later. For release branches, decide whether you rescan on a schedule and who triages new findings.
Safeguard's continuous monitoring watches deployed software against new advisories, so you hear about a changed result when the data moves instead of at the next build. A free scan is at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how monitoring surfaces a finding after the build is done.
Quick check
Does a new finding mean my code got worse?
Not necessarily. The advisory may have been published after your build, so the finding is newly known, not newly introduced.
How do I tell if an advisory was withdrawn?
In the OSV format, a record with a withdrawn timestamp should be treated as withdrawn. If the field is missing, it has not been withdrawn.
Sources
- OpenSSF, OSV schema
Last reviewed: 19 October 2026.