Repack fails when install directory from a previous failed build is not cleaned. Root cause in craft-parts; acknowledged by maintainer with workaround provided.
Suggested action: keep open
Reason: This is a valid bug clearly scoped with a reproducible test case. A maintainer (@lengau) acknowledged the issue and confirmed the root cause is in craft-parts' install directory cleanup after build failure. The related craft-parts#1780 tracks the same underlying problem. A workaround (charmcraft clean files) is provided but the fix is needed.
### Check existing issues
- [x] I've verified that this bug isn't described by any existing issues.
### Bug description
`CHARMCRAFT_EXPERIMENTAL_MONOREPO=1 charmcraft pack` fails with
```
:: + cp --archive --link --no-dereference . /root/parts/files/install
:: cp: cannot create hard link '/root/parts/files/install/./pyproject.toml' to './pyproject.toml': File exists
:: cp: cannot create hard link '/root/parts/files/install/./poetry.lock' to './poetry.lock': File exists
:: cp: cannot create hard link '/root/parts/files/install/./metadata.yaml' to './metadata.yaml': File exists
:: cp: cannot create hard link '/root/parts/files/install/./charmcraft.yaml' to './charmcraft.yaml': File exists
```
after a previous pack failed (for a different reason). Occurs only on repacks, not clean packs
### Steps to reproduce
```
git clone https://github.com/carlcsaposs-canonical/bug-report-charmcraft-monorepo-repack
cd bug-report-charmcraft-monorepo-repack/kubernetes/
CHARMCRAFT_EXPERIMENTAL_MONOREPO=1 charmcraft pack -v
CHARMCRAFT_EXPERIMENTAL_MONOREPO=1 charmcraft pack -v
```
### Environment
LXD, ubuntu 26.04
### charmcraft.yaml
```yaml
type: charm
platforms:
ubuntu@26.04:amd64:
ubuntu@26.04:arm64:
parts:
charm-poetry:
plugin: poetry
source: ..
source-subdir: kubernetes/
files:
plugin: dump
source: ..
source-subdir: kubernetes/
override-build: |
craftctl default
exit 1
```
### Log output
```shell
ubuntu@dualla:~$ git clone https://github.com/carlcsaposs-canonical/bug-report-charmcraft-monorepo-repack
Cloning into 'bug-report-charmcraft-monorepo-repack'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 12 (delta 0), reused 12 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (12/12), done.
ubuntu@dualla:~$ cd bug-report-charmcraft-monorepo-repack/kubernetes/
ubuntu@dualla:~/bug-report-charmcraft-monorepo-repack/kubernetes$ CHARMCRAFT_EXPERIMENTAL_MONOREPO=1 charmcraft pack -v
Starting charmcraft, version 4.5.0
Logging execution to '/home/ubuntu/.local/state/charmcraft/log/charmcraft-20261022-111102.907563.log'
Launching managed ubuntu 26.04 instance...
Creating instance from base instance
Starting instance
Starting charmcraft, version 4.5.0
Logging execution to '/tmp/charmcraft.log'
Initializing lifecycle
Installing build-packages
Pulling charm-poetry
Pulling files
Building charm-poetry
:: + python3 -m venv --without-pip /root/parts/charm-poetry/install/venv
:: + PARTS_PYTHON_VENV_INTERP_PATH=/root/parts/charm-poetry/install/venv/bin/python3
:: + poetry export --format=requirements.txt --output=/root/parts/charm-poetry/build/requirements.txt --with-credentials
:: +++ which python3
:: ++ readlink -f /usr/bin/python3
:: + /usr/bin/python3.14 -m pip --python=/root/parts/charm-poetry/install/venv/bin/python3 install --no-deps --no-binary=:all: --requirement=/root/parts/charm-poetry/build/requirements.txt
:: Processing /root/parts/charm-poetry/build/common (from -r /root/parts/charm-poetry/build/requirements.txt (line 1))
:: Installing build dependencies: started
:: Installing build dependencies: finished with status 'done'
:: Getting requirements to build wheel: started
:: Getting requirements to build wheel: finished with status 'done'
:: Preparing metadata (pyproject.toml): started
:: Preparing metadata (pyproject.toml): finished with status 'done'
:: Building wheels for collected packages: common
:: Building wheel for common (pyproject.toml): started
:: Building wheel for common (pyproject.toml): finished with status 'done'
:: Created wheel for common: filename=common-0.1.0-py2.py3-none-any.whl size=975 sha256=4d1d9b6844cc3bfb99ba8a7d80be6c3004d3cd80fea02c155f14a48ecd7884f7
:: Stored in directory: /tmp/pip-ephem-wheel-cache-2wka7vvg/wheels/d7/fe/b4/644d0c428d267358ff9bf1a023387f1923c76744fe887ce9ff
:: Successfully built common
:: Installing collected packages: common
:: Successfully installed common-0.1.0
:: +++ which python3
:: ++ readlink -f /usr/bin/python3
:: + /usr/bin/python3.14 -m pip --python=/root/parts/charm-poetry/install/venv/bin/python3 check
:: No broken requirements found.
:: ++ set +o
:: ++ grep errexit
:: + opts_state='set +o errexit'
:: + set +e
:: + install_dir=/root/parts/charm-poetry/install/usr/bin
:: + stage_dir=/root/stage/usr/bin
:: +++ readlink -f /root/parts/charm-poetry/install/venv/bin/python3
:: ++ basename /usr/bin/python3.14
:: + basename=python3.14
:: + echo Looking for a Python interpreter called '"python3.14"' in the payload...
:: Looking for a Python interpreter called "python3.14" in the payload...
:: ++ find /root/parts/charm-poetry/install/usr/bin /root/stage/usr/bin -type f -executable -name python3.14 -print -quit
:: ++ true
:: + payload_python=
:: + '[' -n '' ']'
:: + echo 'Python interpreter not found in payload.'
:: Python interpreter not found in payload.
:: +++ which python3
:: ++ readlink -f /usr/bin/python3
:: + symlink_target=/usr/bin/python3.14
:: + '[' -z /usr/bin/python3.14 ']'
:: + eval 'set +o errexit'
:: ++ set +o errexit
:: + echo Removing python symlinks in /root/parts/charm-poetry/install/venv/bin
:: + rm /root/parts/charm-poetry/install/venv/bin/python /root/parts/charm-poetry/install/venv/bin/python3 /root/parts/charm-poetry/install/venv/bin/python3.14
:: Removing python symlinks in /root/parts/charm-poetry/install/venv/bin
:: + shopt -s extglob
:: + rm -rf /root/parts/charm-poetry/install/venv/bin/Activate.ps1 /root/parts/charm-poetry/install/venv/bin/activate.csh /root/parts/charm-poetry/install/venv/bin/activate.fish /root/parts/charm-poetry/install/venv/bin/๐thon
:: + shopt -u extglob
:: + sed -i 's#^VIRTUAL_ENV=.*$#VIRTUAL_ENV="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." \&> /dev/null \&\& pwd )"#' /root/parts/charm-poetry/install/venv/bin/activate
:: + '[' -L /root/parts/charm-poetry/install/venv/lib64 ']'
:: + rm -f /root/parts/charm-poetry/install/venv/lib64
Building files
:: + craftctl default
:: + cp --archive --link --no-dereference . /root/parts/files/install
:: + exit 1
'override-build' in part 'files' failed with code 1.
Detailed information:
:: + craftctl default
:: + exit 1
Recommended resolution: Review the scriptlet and make sure it's correct.
For more information, check out: https://documentation.ubuntu.com/charmcraft/4/reference/plugins/
Failed to run charmcraft in instance
Full execution log: '/home/ubuntu/.local/state/charmcraft/log/charmcraft-20261022-111102.907563.log'
ubuntu@dualla:~/bug-report-charmcraft-monorepo-repack/kubernetes$ CHARMCRAFT_EXPERIMENTAL_MONOREPO=1 charmcraft pack -v
Starting charmcraft, version 4.5.0
Logging execution to '/home/ubuntu/.local/state/charmcraft/log/charmcraft-20261022-111342.742597.log'
Launching managed ubuntu 26.04 instance...
Starting instance
Starting charmcraft, version 4.5.0
Logging execution to '/tmp/charmcraft.log'
Initializing lifecycle
Installing build-packages
Skipping pull for charm-poetry (already ran)
Skipping pull for files (already ran)
Skipping build for charm-poetry (already ran)
Building files
:: + craftctl default
:: + cp --archive --link --no-dereference . /root/parts/files/install
:: cp: cannot create hard link '/root/parts/files/install/./pyproject.toml' to './pyproject.toml': File exists
:: cp: cannot create hard link '/root/parts/files/install/./poetry.lock' to './poetry.lock': File exists
:: cp: cannot create hard link '/root/parts/files/install/./metadata.yaml' to './metadata.yaml': File exists
:: cp: cannot create hard link '/root/parts/files/install/./charmcraft.yaml' to './charmcraft.yaml': File exists
Failed to run the build script for part 'files'.
Detailed information:
:: + cp --archive --link --no-dereference . /root/parts/files/install
:: cp: cannot create hard link '/root/parts/files/install/./pyproject.toml' to './pyproject.toml': File exists
:: cp: cannot create hard link '/root/parts/files/install/./poetry.lock' to './poetry.lock': File exists
:: cp: cannot create hard link '/root/parts/files/install/./metadata.yaml' to './metadata.yaml': File exists
:: cp: cannot create hard link '/root/parts/files/install/./charmcraft.yaml' to './charmcraft.yaml': File exists
Recommended resolution: Check the build output and verify the project can work with the 'dump' plugin.
For more information, check out: https://documentation.ubuntu.com/charmcraft/4/reference/plugins/
Failed to run charmcraft in instance
Full execution log: '/home/ubuntu/.local/state/charmcraft/log/charmcraft-20261022-111342.742597.log'
```
Evaluation history
Date
Model
Scores
Action
Summary
qwen/qwen3.6-35b-a3b
Impact:
45
Quick Win:
20
Complexity:
45
Confidence:
80
Actionability:
80
keep open
Repack fails when install directory from a previous failed build is not cleaned. Root cause in craft-parts; acknowledged by maintainer with workaround provided.
qwen/qwen3.6-35b-a3b
Impact:
35
Quick Win:
18
Complexity:
35
Confidence:
85
Actionability:
80
keep open
Repack fails when install directory not cleaned after previous build failure in dump plugin under CHARMCRAFT_EXPERIMENTAL_MONOREPO
qwen/qwen3.6-35b-a3b
Impact:
35
Quick Win:
18
Complexity:
35
Confidence:
85
Actionability:
80
keep open
Repack fails when install directory not cleaned after previous build failure in dump plugin under CHARMCRAFT_EXPERIMENTAL_MONOREPO
qwen/qwen3.6-35b-a3b
Impact:
40
Quick Win:
16
Complexity:
50
Confidence:
75
Actionability:
80
keep open
Repack fails with hard link errors when using dump plugin after a previous pack failure in CHARMCRAFT_EXPERIMENTAL_MONOREPO mode
Identical root cause: craft-parts does not clean the install directory after a build failure, causing subsequent builds to fail with hard-link conflicts.
Related issues
No related issues found above the similarity threshold.