Repository navigation
Description
What happened:
When a scanned directory contains several SPDX documents, the sbom-cataloger merges packages from different documents that use the same SPDXID. The merged package keeps the name, version and purl of one document, but collects the licenses and locations of all of them. The packages from the other documents are not reported.
SPDX element IDs only need to be unique within one document (SPDX 2.3, clause 7.2), so reusing an ID such as SPDXRef-Package across documents is valid. This happens in practice with Python wheels that embed PEP 770 SBOMs (*.dist-info/sboms/*.spdx.json) generated by a tool that uses fixed IDs. Scanning a site-packages directory then reports one package instead of one per wheel, with licenses from unrelated packages attached to it.
What you expected to happen:
One package per SPDX package element, each with only its own licenses and location, as when the IDs differ.
Steps to reproduce the issue:
Two SPDX documents describing different packages, both using SPDXRef-Package:
repro/alpha.spdx.json:
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "alpha-1.0",
"documentNamespace": "https://example.com/spdx/alpha-1.0",
"creationInfo": {"created": "2026-01-01T00:00:00Z", "creators": ["Tool: example"]},
"packages": [
{
"SPDXID": "SPDXRef-Package",
"name": "alpha",
"versionInfo": "1.0",
"downloadLocation": "NOASSERTION",
"licenseDeclared": "MIT",
"externalRefs": [{"referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", "referenceLocator": "pkg:pypi/alpha@1.0"}]
}
],
"relationships": [{"spdxElementId": "SPDXRef-DOCUMENT", "relationshipType": "DESCRIBES", "relatedSpdxElement": "SPDXRef-Package"}]
}repro/beta.spdx.json: the same, with alpha β beta, 1.0 β 2.0 and MIT β Apache-2.0.
$ syft scan dir:repro --override-default-catalogers sbom-cataloger -q
NAME VERSION TYPE
alpha 1.0 pythonIn the JSON output (-o syft-json), the single package is alpha 1.0 (pkg:pypi/alpha@1.0) with licenses ["Apache-2.0", "MIT"] and locations ["/alpha.spdx.json", "/beta.spdx.json"]. beta is missing.
With the IDs changed to SPDXRef-Package-alpha and SPDXRef-Package-beta, both packages are reported, each with its own license and location:
$ syft scan dir:unique --override-default-catalogers sbom-cataloger -q
NAME VERSION TYPE
alpha 1.0 python
beta 2.0 pythonAnything else we need to know?:
The same happens when the documents describe the same package name and version with different data, e.g. two builds of one release from different indexes. Syft reports one package with the purl of the first document and the union of both documents' licenses. By contrast, the python-installed-package-cataloger reports one package per install location, even for identical installs.
Environment:
- Output of
syft version: 1.56.0 (ghcr.io/anchore/syft:latest, built 2026-11-02) - OS: Fedora 44 host, syft run in a container with podman
Activity