Is there an existing issue for this?
This issue exists in the latest npm version
Current Behavior
#6967 (PR #7992, shipped in 11.13.0) deduplicates top-level entries in components / dependencies (CycloneDX) and packages (SPDX) by name@version. However the per-node child arrays — CycloneDX dependsOn and
SPDX DEPENDENCY_OF relationships — are still emitted without deduplication.
This happens whenever a single node has multiple edgesOut resolving to the same name@version. The most common trigger is npm's package aliasing, where a package.json declares both a direct dependency and an alias
to the same underlying package:
{
"dependencies": {
"lodash": "^4.17.21",
"lodash-aliased": "npm:lodash@^4.17.21"
}
}
Both edges resolve to lodash@4.18.1. In lib/utils/sbom-cyclonedx.js, toCyclonedxDependency does:
dependsOn: [...node.edgesOut.values()]
.filter(edge => nodes.find(n => n === edge.to))
.map(edge => toCyclonedxID(edge.to))
.filter(id => id),
toCyclonedxID returns ${packageName}@${version}, so two edges to the same package collapse to the same string and both end up in the array. The same shape exists in lib/utils/sbom-spdx.js for DEPENDENCY_OF
relationships.
CycloneDX 1.5 schema requires dependsOn arrays to have unique items, so downstream consumers that validate against the schema (e.g. Dependency Track) reject the SBOM:
$.dependencies[1557].dependsOn: must have only unique items in the array
Expected Behavior
Each dependsOn array (CycloneDX) and each set of DEPENDENCY_OF relationships from a single source (SPDX) contains a given name@version at most once.
Steps To Reproduce
mkdir sbom-alias-repro && cd sbom-alias-repro
cat > package.json <<'EOF'
{
"name": "sbom-alias-repro",
"version": "1.0.0",
"dependencies": {
"lodash": "^4.17.21",
"lodash-aliased": "npm:lodash@^4.17.21"
}
}
EOF
npm install --package-lock-only
npm sbom --sbom-format cyclonedx --package-lock-only | jq '.dependencies[0]'
Output (npm 11.13.0):
{
"ref": "sbom-alias-repro@1.0.0",
"dependsOn": [
"lodash@4.18.1",
"lodash@4.18.1"
]
}
The same project with --sbom-format spdx emits two identical DEPENDENCY_OF relationships from lodash to the root package.
Environment
- npm: 11.13.0
- Node.js: 22.22.2
- OS: macOS (also reproduces on Linux CI)
Is there an existing issue for this?
This issue exists in the latest npm version
Current Behavior
#6967 (PR #7992, shipped in 11.13.0) deduplicates top-level entries in
components/dependencies(CycloneDX) andpackages(SPDX) byname@version. However the per-node child arrays — CycloneDXdependsOnandSPDX
DEPENDENCY_OFrelationships — are still emitted without deduplication.This happens whenever a single node has multiple
edgesOutresolving to the samename@version. The most common trigger is npm's package aliasing, where apackage.jsondeclares both a direct dependency and an aliasto the same underlying package:
{ "dependencies": { "lodash": "^4.17.21", "lodash-aliased": "npm:lodash@^4.17.21" } }Both edges resolve to
lodash@4.18.1. Inlib/utils/sbom-cyclonedx.js,toCyclonedxDependencydoes:toCyclonedxIDreturns${packageName}@${version}, so two edges to the same package collapse to the same string and both end up in the array. The same shape exists inlib/utils/sbom-spdx.jsforDEPENDENCY_OFrelationships.
CycloneDX 1.5 schema requires
dependsOnarrays to have unique items, so downstream consumers that validate against the schema (e.g. Dependency Track) reject the SBOM:Expected Behavior
Each
dependsOnarray (CycloneDX) and each set ofDEPENDENCY_OFrelationships from a single source (SPDX) contains a givenname@versionat most once.Steps To Reproduce
Output (npm 11.13.0):
{ "ref": "sbom-alias-repro@1.0.0", "dependsOn": [ "lodash@4.18.1", "lodash@4.18.1" ] }The same project with
--sbom-format spdxemits two identicalDEPENDENCY_OFrelationships fromlodashto the root package.Environment