Marking deb packages fails with versioned interdependencies
Metadata
Current evaluation
Fixed by PR #1446 in commit cf118b5f: mark_packages now sets all candidate versions before marking packages for installation, preventing order-dependent failures.
Resolution: closed resolved
Reason: PR #1446 was merged as commit cf118b5f and changed mark_packages to resolve and pin every requested version before marking any package, with regression coverage for versioned interdependencies.
Evaluated by: mr-cal-bot
No scores available.
Issue body
### Bug Description
`AptCache.mark_packages` in `craft_parts/packages/apt_cache.py` resolves package names, sets candidate versions, and calls `mark_install` all within a single loop iteration per package. When two or more packages in the same set have exact-version dependencies on each other, the order in which they are processed determines whether `mark_install` succeeds. Because the input is a `set[str]`, iteration order is non-deterministic.
### Example
Given these packages to mark:
```
libnvinfer-dev=10.14.1.48-1+cuda12.9
libnvinfer10=10.14.1.48-1+cuda12.9
```
`libnvinfer-dev` has an exact dependency: `Depends: libnvinfer10 (= 10.14.1.48-1+cuda12.9)`.
If `libnvinfer-dev` is processed first:
1. Its candidate is set to `10.14.1.48`.
2. `mark_install` runs and evaluates the dependency on `libnvinfer10`.
3. `libnvinfer10` has **not been processed yet**, so its candidate is still the repository default (e.g. `10.15.1.29`).
4. The resolver sees a version mismatch and the mark fails silently (with `auto_fix=False`).
5. `_verify_marked_install` raises `PackageNotFound` because the candidate was invalidated.
The user sees:
```
Cannot find package listed in 'build-packages': libnvinfer-dev
```
This is misleading -- the package exists, but its dependency's candidate version had not been pinned yet.
### Real-world trigger
This shows up when using snapcraft with NVIDIA's CUDA repository and pinning TensorRT packages to a specific version while a newer version also exists in the repo:
### To Reproduce
Add the deb repository.
Stage packages with specific version numbers
- ibnvinfer10=10.14.1.48-1+cuda12.9
- libnvinfer-headers-dev=10.14.1.48-1+cuda12.9
- libnvinfer-dev=10.14.1.48-1+cuda12.9
- cuda-cudart-12-9
In the `part yaml` section I included the snapcraft.yaml to reproduce it.
The proposed fix has a failing test (before applying the fix) :
```
tests/unit/packages/test_apt_cache.py:191:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
craft_parts/packages/apt_cache.py:328: in mark_packages
_verify_marked_install(package)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
package = <MagicMock id='136220264840544'>
def _verify_marked_install(package: apt.package.Package) -> None:
if package.installed or package.marked_install:
return
if package.candidate is None:
> raise errors.PackageNotFound(package.name)
E craft_parts.packages.errors.PackageNotFound: Package not found: libnvinfer-dev.
```
### part yaml
```shell
name: tensorrt-test
base: core22
version: '0.1'
summary: Test snap for TensorRT library installation
description: |
This snap demonstrates installing TensorRT libraries from NVIDIA CUDA
developer repository on Ubuntu 22.04.
grade: devel
confinement: devmode
# Add NVIDIA CUDA developer repository using path for flat repository
package-repositories:
- type: apt
formats: [deb]
path: /
key-id: EB693B3035CD5710E231E123A4B469963BF863CC
key-server: keyserver.ubuntu.com
url: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64
parts:
tensorrt:
plugin: nil
build-packages:
- cuda-toolkit-12-9
stage-packages:
- libnvinfer10=10.14.1.48-1+cuda12.9
- libnvinfer-headers-dev=10.14.1.48-1+cuda12.9
- libnvinfer-dev=10.14.1.48-1+cuda12.9
- cuda-cudart-12-9
- bash
apps:
test:
command: bin/bash
```
### Relevant log output
```shell
2026-01-31 11:18:06.748 Installed package repositories
2026-01-31 11:18:06.750 part build packages: ['cuda-toolkit-12-9', 'libnvinfer-dev=10.14.1.48-1+cuda12.9', 'libnvinfer-headers-dev=10.14.1.48-1+cuda12.9', 'libnvinfer10=10.14.1.48-1+cuda12.9']
2026-01-31 11:18:06.750 Installing build-packages
2026-01-31 11:18:06.750 Requested build-packages: ['cuda-toolkit-12-9', 'libnvinfer-dev=10.14.1.48-1+cuda12.9', 'libnvinfer-headers-dev=10.14.1.48-1+cuda12.9', 'libnvinfer10=10.14.1.48-1+cuda12.9']
2026-01-31 11:18:10.222 Marking libnvinfer10=10.14.1.48-1+cuda12.9 (and its dependencies) to be fetched
2026-01-31 11:18:10.237 package: libnvinfer10
2026-01-31 11:18:10.305 Marking libnvinfer-dev=10.14.1.48-1+cuda12.9 (and its dependencies) to be fetched
2026-01-31 11:18:10.325 package: libnvinfer-dev
2026-01-31 11:18:10.347 Cannot find package listed in 'build-packages': libnvinfer-dev
2026-01-31 11:18:10.349 Traceback (most recent call last):
2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/snapcraft/application.py", line 473, in main
2026-01-31 11:18:10.349 return app.run()
2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/craft_application/application.py", line 623, in run
2026-01-31 11:18:10.349 return_code = self._run_inner()
2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/snapcraft/application.py", line 184, in _run_inner
2026-01-31 11:18:10.349 return_code = super()._run_inner()
2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/craft_application/application.py", line 569, in _run_inner
2026-01-31 11:18:10.349 dispatcher = self._get_dispatcher()
2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/snapcraft/application.py", line 411, in _get_dispatcher
2026-01-31 11:18:10.350 self._check_for_classic_fallback()
2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/snapcraft/application.py", line 323, in _check_for_classic_fallback
2026-01-31 11:18:10.350 raise errors.ClassicFallback()
2026-01-31 11:18:10.350 snapcraft.errors.ClassicFallback
2026-01-31 11:18:10.350
2026-01-31 11:18:10.350 During handling of the above exception, another exception occurred:
2026-01-31 11:18:10.350 Traceback (most recent call last):
2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 509, in _get_packages_marked_for_installation
2026-01-31 11:18:10.350 apt_cache.mark_packages(set(package_names))
2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/craft_parts/packages/apt_cache.py", line 328, in mark_packages
2026-01-31 11:18:10.350 _verify_marked_install(package)
2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/craft_parts/packages/apt_cache.py", line 375, in _verify_marked_install
2026-01-31 11:18:10.350 raise errors.PackageNotFound(package.name)
2026-01-31 11:18:10.350 craft_parts.packages.errors.PackageNotFound: Package not found: libnvinfer-dev.
2026-01-31 11:18:10.351
2026-01-31 11:18:10.351 The above exception was the direct cause of the following exception:
2026-01-31 11:18:10.351 Traceback (most recent call last):
2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/snapcraft/parts/parts.py", line 204, in run
2026-01-31 11:18:10.351 with self._lcm.action_executor() as aex:
2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/executor/executor.py", line 319, in __enter__
2026-01-31 11:18:10.351 self._executor.prologue()
2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/executor/executor.py", line 88, in prologue
2026-01-31 11:18:10.351 self._install_build_packages()
2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/executor/executor.py", line 261, in _install_build_packages
2026-01-31 11:18:10.351 packages.Repository.install_packages(sorted(build_packages))
2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 566, in install_packages
2026-01-31 11:18:10.351 marked_packages = cls._get_packages_marked_for_installation(package_names)
2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 293, in wrapped
2026-01-31 11:18:10.351 return method(*args, **kwargs)
2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 511, in _get_packages_marked_for_installation
2026-01-31 11:18:10.351 raise errors.BuildPackageNotFound(error.package_name) from error
2026-01-31 11:18:10.351 craft_parts.packages.errors.BuildPackageNotFound: Cannot find package listed in 'build-packages': libnvinfer-dev
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha | — | closed resolved | Fixed by PR #1446 in commit cf118b5f: mark_packages now sets all candidate versions before marking packages for installation, preventing order-dependent failures. | |
| stealth/space-bunny-alpha | — | closed stale | Closed without a documented fix, replacement, or maintainer explanation; versioned interdependency handling remains unverified. | |
| qwen/qwen3.6-35b-a3b | — | — | Closed and fixed. Resolved by replacing the non-deterministic set iteration in mark_packages with a sorted list, ensuring versioned interdependencies are processed consistently before marking installation. | |
| qwen/qwen3.6-35b-a3b | — | — | Closed. Fixed by enforcing deterministic iteration order in mark_packages, resolving silent failures when marking deb packages with exact-version interdependencies. | |
| qwen/qwen3.6-35b-a3b | — | — | Closed after a fix was implemented to resolve the non-deterministic iteration order in mark_packages, ensuring versioned interdependencies are processed correctly and preventing misleading PackageNotFound errors. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Fixed by ensuring mark_packages processes versioned interdependencies deterministically, resolving silent apt cache failures and misleading PackageNotFound errors. |
Update history
No update history recorded yet.
Related work
-
Likely Fixed By:
canonical/craft-parts#1446
(confidence 99%)
Commit cf118b5f implements the two-pass candidate-pinning fix described in issue #1444.
Related issues
No related issues found above the similarity threshold.