Packing a charm sometimes fails with "Too many levels of symbolic links"
Metadata
Current evaluation
Charm packing fails with a symbolic link error when .tox or .venv directories are present, and the issue remains open with contributors actively reproducing it and discussing workarounds.
Suggested action: needs triage
Reason: The issue is a valid bug report but lacks maintainer labels, assignees, or prior assessment. It requires initial triage to verify reproducibility, prioritize, and categorize appropriately.
Staleness:
25
Complexity:
40
Confidence:
85
Support Request:
0
Issue body
### Check existing issues
- [x] I've verified that this bug isn't described by any existing issues.
### Bug description
Packing a charm that has a `.tox` or a `.venv` directory can fail with a "Too many levels of symbolic links" error:
```text
OSError: [Errno 40] Too many levels of symbolic links: '/root/project/.tox/lint/lib64'
```
and
```text
OSError: [Errno 40] Too many levels of symbolic links: '/home/ubuntu/tinyproxy/.venv/bin/python3.12'
```
See the log output below for more context.
I haven't been able to reproduce this myself, but @james-garner-canonical and I have observed other people running into the issue.
The context is:
- Working inside a Multipass VM on a Mac
- Used tox to run a development command (so that `.tox` is created) or used uv to manage the charm's dependencies (so that `.venv` is created)
- Then packed the charm, not using destructive mode
If packing fails, deleting `.tox`/`.venv` before packing again seems to help. Using destructive mode seems to help. (I'm sorry these resolution steps aren't more precise.)
### Steps to reproduce
See above
### Environment
Multipass on a Mac. Not destructive mode.
### charmcraft.yaml
```yaml
# This file configures Charmcraft.
# See https://documentation.ubuntu.com/charmcraft/stable/reference/files/charmcraft-yaml-file/
type: charm
name: tinyproxy
title: Reverse Proxy Demo
summary: A demo charm that configures tinyproxy as a reverse proxy.
description: |
This charm demonstrates how to write a machine charm with Ops.
# Documentation:
# https://documentation.ubuntu.com/charmcraft/stable/howto/build-guides/select-platforms/
base: ubuntu@24.04
platforms:
amd64:
arm64:
assumes:
- juju >= 3.6
parts:
charm:
plugin: uv
source: .
build-snaps:
- astral-uv
# (Optional) Configuration options for the charm
# This config section defines charm config options, and populates the Configure
# tab on Charmhub.
# More information on this section at:
# https://documentation.ubuntu.com/charmcraft/stable/reference/files/charmcraft-yaml-file/#config
# General configuration documentation:
# https://documentation.ubuntu.com/juju/3.6/reference/configuration/#application-configuration
config:
options:
slug:
description: "Configures the path of the reverse proxy. Must match the regex [a-z0-9-]+"
default: example
type: string
```
### Log output
```shell
:: ## User environment
:: 2026-03-26 08:32:23.513 plugin validation command: 'uv --version'
:: 2026-03-26 08:32:23.739 executed uv --version with output uv 0.11.1 (a6042f67f 2026-03-24 aarch64-unknown-linux-gnu)
:: 2026-03-26 08:32:23.739 set repository attribute: attr=stage_packages_filters, value=None, repo:<class 'craft_parts.packages.deb.Ubuntu'>
:: 2026-03-26 08:32:23.739 Pulling charm
:: 2026-03-26 08:32:23.739 execute action charm:Action(part_name='charm', step=Step.PULL, action_type=ActionType.RUN, reason=None, project_vars=ProjectVarInfo(root={}), properties=ActionProperties(changed_files=None, changed_dirs=None))
:: 2026-03-26 08:32:23.921 /root/project/.tox/lint/lib64: Too many levels of symbolic links
:: 2026-03-26 08:32:23.921 Detailed information: OSError: filename: '/root/project/.tox/lint/lib64'
:: 2026-03-26 08:32:23.924 Traceback (most recent call last):
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 96, in link_or_copy
:: 2026-03-26 08:32:23.924 copy(source, destination)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 173, in copy
:: 2026-03-26 08:32:23.924 shutil.copy2(source, destination, follow_symlinks=follow_symlinks)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/current/usr/lib/python3.12/shutil.py", line 476, in copy2
:: 2026-03-26 08:32:23.924 copystat(src, dst, follow_symlinks=follow_symlinks)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/current/usr/lib/python3.12/shutil.py", line 388, in copystat
:: 2026-03-26 08:32:23.924 _copyxattr(src, dst, follow_symlinks=follow)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/current/usr/lib/python3.12/shutil.py", line 330, in _copyxattr
:: 2026-03-26 08:32:23.924 names = os.listxattr(src, follow_symlinks=follow_symlinks)
:: 2026-03-26 08:32:23.924 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:: 2026-03-26 08:32:23.924 OSError: [Errno 40] Too many levels of symbolic links: '/root/project/.tox/lint/lib64'
:: 2026-03-26 08:32:23.924
:: 2026-03-26 08:32:23.924 During handling of the above exception, another exception occurred:
:: 2026-03-26 08:32:23.924 Traceback (most recent call last):
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/services/lifecycle.py", line 318, in run
:: 2026-03-26 08:32:23.924 self._exec(actions)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/services/lifecycle.py", line 342, in _exec
:: 2026-03-26 08:32:23.924 aex.execute(action, stdout=stream, stderr=stream)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/executor.py", line 342, in execute
:: 2026-03-26 08:32:23.924 self._executor.execute(actions, stdout=stdout, stderr=stderr)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/executor.py", line 136, in execute
:: 2026-03-26 08:32:23.924 self._run_action(act, stdout=stdout, stderr=stderr)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/executor.py", line 229, in _run_action
:: 2026-03-26 08:32:23.924 handler.run_action(action, stdout=stdout, stderr=stderr)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/part_handler.py", line 309, in run_action
:: 2026-03-26 08:32:23.924 state = handler(step_info, stdout=stdout, stderr=stderr)
:: 2026-03-26 08:32:23.924 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/part_handler.py", line 335, in _run_pull
:: 2026-03-26 08:32:23.924 self._run_step(
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/part_handler.py", line 674, in _run_step
:: 2026-03-26 08:32:23.924 return step_handler.run_builtin()
:: 2026-03-26 08:32:23.924 ^^^^^^^^^^^^^^^^^^^^^^^^^^
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/step_handler.py", line 139, in run_builtin
:: 2026-03-26 08:32:23.924 return handler()
:: 2026-03-26 08:32:23.924 ^^^^^^^^^
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/executor/step_handler.py", line 143, in _builtin_pull
:: 2026-03-26 08:32:23.924 self._source_handler.pull()
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/sources/local_source.py", line 105, in pull
:: 2026-03-26 08:32:23.924 file_utils.link_or_copy_tree(
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 255, in link_or_copy_tree
:: 2026-03-26 08:32:23.924 copy_function(source, destination)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 111, in link_or_copy
:: 2026-03-26 08:32:23.924 copy(source, destination, follow_symlinks=follow_symlinks)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 173, in copy
:: 2026-03-26 08:32:23.924 shutil.copy2(source, destination, follow_symlinks=follow_symlinks)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/current/usr/lib/python3.12/shutil.py", line 476, in copy2
:: 2026-03-26 08:32:23.924 copystat(src, dst, follow_symlinks=follow_symlinks)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/current/usr/lib/python3.12/shutil.py", line 388, in copystat
:: 2026-03-26 08:32:23.924 _copyxattr(src, dst, follow_symlinks=follow)
:: 2026-03-26 08:32:23.924 File "/snap/charmcraft/current/usr/lib/python3.12/shutil.py", line 330, in _copyxattr
:: 2026-03-26 08:32:23.924 names = os.listxattr(src, follow_symlinks=follow_symlinks)
:: 2026-03-26 08:32:23.924 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:: 2026-03-26 08:32:23.924 OSError: [Errno 40] Too many levels of symbolic links: '/root/project/.tox/lint/lib64'
2026-03-26 08:32:24.278 Executing on host: lxc --project charmcraft config device show local:charmcraft-tinyproxy-arm64-975
2026-03-26 08:32:24.347 Executing on host: lxc --project charmcraft config device remove local:charmcraft-tinyproxy-arm64-975 disk-/root/.cache/pip
2026-03-26 08:32:24.433 Executing on host: lxc --project charmcraft config device remove local:charmcraft-tinyproxy-arm64-975 disk-/root/project
2026-03-26 08:32:24.513 Executing on host: lxc --project charmcraft config device remove local:charmcraft-tinyproxy-arm64-975 disk-/tmp/craft-state
2026-03-26 08:32:24.599 Executing on host: lxc --project charmcraft stop local:charmcraft-tinyproxy-arm64-975
2026-03-26 08:32:28.532 Executing on host: lxc --project charmcraft list local: --format=yaml
2026-03-26 08:32:28.613 Executing on host: lxc --project charmcraft list local: --format=yaml
2026-03-26 08:32:28.735 Executing on host: lxc --project charmcraft list local: --format=yaml
2026-03-26 08:32:28.880 Executing on host: lxc --project charmcraft config set local:charmcraft-tinyproxy-arm64-975 user.craft_providers.status FINISHED
2026-03-26 08:32:28.969 Failed to run charmcraft in instance
2026-03-26 08:32:28.980 Traceback (most recent call last):
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/services/provider.py", line 471, in run_managed
2026-03-26 08:32:28.980 instance.execute_run( # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_providers/lxd/lxd_instance.py", line 257, in execute_run
2026-03-26 08:32:28.980 return self.lxc.exec(
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_providers/lxd/lxc.py", line 393, in exec
2026-03-26 08:32:28.980 return runner(final_cmd, timeout=timeout, check=check, **kwargs)
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/current/usr/lib/python3.12/subprocess.py", line 571, in run
2026-03-26 08:32:28.980 raise CalledProcessError(retcode, process.args,
2026-03-26 08:32:28.980 subprocess.CalledProcessError: Command '['lxc', '--project', 'charmcraft', 'exec', 'local:charmcraft-tinyproxy-arm64-975', '--cwd', '/root/project', '--', 'env', 'CRAFT_MANAGED_MODE=1', 'CHARMCRAFT_DEBUG=False', 'CHARMCRAFT_LXD_REMOTE=local', 'CHARMCRAFT_LAUNCHPAD_INSTANCE=production', 'CHARMCRAFT_MANAGED_MODE=1', 'DEBIAN_FRONTEND=noninteractive', 'DEBCONF_NONINTERACTIVE_SEEN=true', 'DEBIAN_PRIORITY=critical', 'CRAFT_PLATFORM=arm64', 'CRAFT_VERBOSITY_LEVEL=BRIEF', 'charmcraft', 'pack']' returned non-zero exit status 1.
2026-03-26 08:32:28.980
2026-03-26 08:32:28.980 The above exception was the direct cause of the following exception:
2026-03-26 08:32:28.980 Traceback (most recent call last):
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/application.py", line 663, in run
2026-03-26 08:32:28.980 return_code = self._run_inner()
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/charmcraft/application/main.py", line 143, in _run_inner
2026-03-26 08:32:28.980 return super()._run_inner()
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/application.py", line 640, in _run_inner
2026-03-26 08:32:28.980 return_code = dispatcher.run() or os.EX_OK
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_cli/dispatcher.py", line 564, in run
2026-03-26 08:32:28.980 return self._loaded_command.run(self._parsed_command_args)
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/commands/base.py", line 200, in run
2026-03-26 08:32:28.980 result = self._run(parsed_args, **kwargs) or result
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/charmcraft/application/commands/lifecycle.py", line 167, in _run
2026-03-26 08:32:28.980 result = super()._run(parsed_args, step_name, **kwargs)
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/commands/lifecycle.py", line 619, in _run
2026-03-26 08:32:28.980 return super()._run(parsed_args=parsed_args, step_name=step_name)
2026-03-26 08:32:28.980 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/commands/lifecycle.py", line 232, in _run
2026-03-26 08:32:28.980 self._run_manager_for_build_plan(fetch_service_policy)
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/commands/lifecycle.py", line 97, in _run_manager_for_build_plan
2026-03-26 08:32:28.980 provider.run_managed(build, bool(fetch_service_policy))
2026-03-26 08:32:28.980 File "/snap/charmcraft/7519/lib/python3.12/site-packages/craft_application/services/provider.py", line 478, in run_managed
2026-03-26 08:32:28.980 raise craft_providers.ProviderError(
2026-03-26 08:32:28.980 craft_providers.errors.ProviderError: Failed to run charmcraft in instance
2026-03-26 08:32:28.980 Full execution log: '/home/ubuntu/.local/state/charmcraft/log/charmcraft-20260326-082831.211082.log'
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| 2026-06-15 11:55:59.964838+00:00 | qwen3.6-35b-a3b-mtp-q6 |
Staleness:
25
Complexity:
40
Confidence:
85
Support Request:
0
|
needs triage | Charm packing fails with a symbolic link error when .tox or .venv directories are present, and the issue remains open with contributors actively reproducing it and discussing workarounds. |
| 2026-06-15 11:53:46.305460+00:00 | pending | — | — | — |