In CycloneDX, a component declared with an empty dependsOn list has no dependencies. A component that does not appear in the dependency graph at all may have unknown dependencies, and the spec says not to read its absence as dependency-free. For unknown graphs, use compositions to say so.
What the schema says
The CycloneDX 1.6 JSON reference describes the dependencies array as defining the direct dependencies of a component or service. It states that components or services without their own dependencies must be declared as empty elements within the graph, and that those not represented in the graph may have unknown dependencies. It recommends that implementations assume the graph to be opaque and not an indicator of an object being dependency-free, and recommends using compositions to indicate unknown dependency graphs.
Each entry has a ref, pointing at a component's bom-ref, and a dependsOn list of other bom-refs.
"dependencies": [
{ "ref": "app", "dependsOn": ["lib-a", "lib-b"] },
{ "ref": "lib-a", "dependsOn": [] },
{ "ref": "lib-b", "dependsOn": ["lib-c"] }
]
Here lib-a is stated to have none. lib-c has no entry, so nothing is claimed about it.
Three states, three meanings
| State in the file | What it means |
|---|---|
| Entry with dependsOn listing refs | Direct dependencies are known |
| Entry with an empty dependsOn | Explicitly none |
| No entry at all | Unknown, per the spec's guidance |
A generator that omits entries for leaf packages is not wrong by the loose reading, but it forces every reader to guess, so empty entries are better.
Why it matters for incident work
When a new vulnerability lands in lib-c, you want to know every path to it. If your SBOM tool assumes missing entries mean no dependencies, it may under-report. If it assumes missing means unknown, it should show a warning. Test your own tool with a file like the one above and see which behavior you get.
Flagging the gaps
The spec points to compositions for stating how complete parts of the BOM are. An aggregate value such as unknown dependencies, or incomplete, tells the reader which part of the graph to treat with caution. Use it when your generator could not resolve a part of the tree, for example when it read only a manifest and not a lockfile.
A short checklist
Does every component appear as a ref at least once? Do leaf components have explicit empty lists? Are there compositions entries for any area you could not resolve? Does your validation step fail when a dependsOn names a bom-ref that does not exist? Four yes answers means a graph you can rely on during a response.
Safeguard can generate SBOMs and run dependency scanning across your repositories, so the fields discussed here are checked on real projects instead of by hand. You can try the free scan at gold.safeguard.sh/scan.
Try it yourself
Open the demo, click through the component list, and look at how each package is identified and what is missing.
Click through it at your own pace, or open it full screen.
Quick check
What does an empty dependsOn mean?
In CycloneDX it states the component has no dependencies. The spec says components without dependencies must be declared as empty elements.
How do I say the graph is incomplete?
Use compositions, which the spec recommends for indicating unknown dependency graphs.
Sources
Last reviewed: 19 October 2026.