Remote build fails on dangling symlinks
Metadata
Current evaluation
Closed without resolution. Remote-build crashes during project directory copying when dangling symlinks are present, causing a shutil.Error. No fix or follow-up was provided.
Suggested action: —
No scores available.
Issue body
### Bug Description
Attempting to use `remote-build` while in a directory that has dangling symlinks fails. This failure mode should not be forced by the craft tool, but rather should become a failure by the consuming build tools that the craft tool invokes (if it even _is_ an error).
### To Reproduce
Create a broken symlink in any project, commit it, and then attempt to run `remote-build`.
For example,
```
├── here -> to-here # `to-here` doesn't exist!
└── snap
└── snapcraft.yaml
```
### part yaml
```shell
Irrelevant
```
### Relevant log output
```shell
2026-06-25 11:18:42.312 Starting snapcraft, version 9.0.0
2026-06-25 11:18:42.312 Log verbosity level set to BRIEF
2026-06-25 11:18:42.312 Setting up Project
2026-06-25 11:18:42.312 Project file found at '/home/imani/work/scratch/snap/snapcraft.yaml'
2026-06-25 11:18:42.312 Loading project file 'snap/snapcraft.yaml
2026-06-25 11:18:42.313 Setting up BuildPlan
2026-06-25 11:18:42.313 Build plan contains 1 build(s).
2026-06-25 11:18:42.315 Loading app plugin sdplug
2026-06-25 11:18:42.338 Forward environment variables
2026-06-25 11:18:42.338 Registering craft-sd source handlers
2026-06-25 11:18:42.338 Registering craft-sd services
2026-06-25 11:18:42.338 SD not enabled. Skipping adding commands
2026-06-25 11:18:42.338 Request craft-sd snap installation in managed instance
2026-06-25 11:18:42.338 Skipping store secrets callback registration: SD not enabled.
2026-06-25 11:18:42.338 Preparing application...
2026-06-25 11:18:42.338 Setting up ConfigService
2026-06-25 11:18:42.342 Merging commands for group 'Lifecycle':
2026-06-25 11:18:42.342 - using application command for 'clean'.
2026-06-25 11:18:42.342 - using application command for 'pull'.
2026-06-25 11:18:42.342 - using application command for 'build'.
2026-06-25 11:18:42.342 - using application command for 'stage'.
2026-06-25 11:18:42.342 - using application command for 'prime'.
2026-06-25 11:18:42.342 - using application command for 'pack'.
2026-06-25 11:18:42.342 Merging commands for group 'Other':
2026-06-25 11:18:42.342 Configuring application...
2026-06-25 11:18:42.346 Build plan: platform=None, build_for=None
2026-06-25 11:18:42.346 Running snapcraft remote-build on host
2026-06-25 11:18:42.346 remote-build is experimental and is subject to change. Use with caution.
2026-06-25 11:18:42.346 Setting up RequestService
2026-06-25 11:18:42.346 Logging in with credentials file /home/imani/.local/share/snapcraft/launchpad-credentials.
2026-06-25 11:18:42.346 Emitter: Pausing control of the terminal
2026-06-25 11:18:47.629 Emitter: Resuming control of the terminal
2026-06-25 11:18:47.629 Trying to get project scratch (attempt 1/6)
2026-06-25 11:18:47.936 Emitter: Pausing control of the terminal
2026-06-25 11:18:48.750 Emitter: Resuming control of the terminal
2026-06-25 11:18:48.750 Build plan contains 1 build(s).
2026-06-25 11:18:48.750 Using '--build-for' as the list of architectures to build for
2026-06-25 11:18:48.750 Architectures to build for: 'amd64'
2026-06-25 11:18:48.750 Created project variables {'version': {'value': '0.1', 'updated': False, 'part-name': None}, 'grade': {'value': 'devel', 'updated': False, 'part-name': None}}.
2026-06-25 11:18:48.751 Using parallel build count of 16 from CPU count
2026-06-25 11:18:48.751 Checking if 'version' exists.
2026-06-25 11:18:48.751 Getting value for 'version'.
2026-06-25 11:18:48.751 Got '0.1' (updated=False) for 'version'.
2026-06-25 11:18:48.751 'version' exists.
2026-06-25 11:18:48.751 Getting value for 'version'.
2026-06-25 11:18:48.751 Got '0.1' (updated=False) for 'version'.
2026-06-25 11:18:48.751 Checking if 'version' exists.
2026-06-25 11:18:48.751 Getting value for 'version'.
2026-06-25 11:18:48.751 Got '0.1' (updated=False) for 'version'.
2026-06-25 11:18:48.751 'version' exists.
2026-06-25 11:18:48.751 Getting value for 'version'.
2026-06-25 11:18:48.751 Got '0.1' (updated=False) for 'version'.
2026-06-25 11:18:48.751 Checking if 'grade' exists.
2026-06-25 11:18:48.751 Getting value for 'grade'.
2026-06-25 11:18:48.751 Got 'devel' (updated=False) for 'grade'.
2026-06-25 11:18:48.751 'grade' exists.
2026-06-25 11:18:48.751 Getting value for 'grade'.
2026-06-25 11:18:48.751 Got 'devel' (updated=False) for 'grade'.
2026-06-25 11:18:48.751 Processing grammar (on amd64 for amd64)
2026-06-25 11:18:48.751 Processing grammar for plugin: nil
2026-06-25 11:18:48.757 Starting new build. It may take a while to upload large projects.
2026-06-25 11:18:48.759 snapcraft internal error: Error([('/home/imani/work/scratch/here', '/home/imani/.cache/snapcraft/remote-build/snapcraft-scratch-a22566aae87cb46312173f84fc845a49/repo/here', "[Errno 2] No such file or directory: '/home/imani/work/scratch/here'")])
2026-06-25 11:18:48.771 Traceback (most recent call last):
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_application/application.py", line 693, in run
2026-06-25 11:18:48.771 return_code = self._run_inner()
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/snapcraft/application.py", line 180, in _run_inner
2026-06-25 11:18:48.771 return_code = super()._run_inner()
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_application/application.py", line 670, in _run_inner
2026-06-25 11:18:48.771 return_code = dispatcher.run() or os.EX_OK
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_cli/dispatcher.py", line 576, in run
2026-06-25 11:18:48.771 return self._loaded_command.run(self._parsed_command_args)
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_application/commands/base.py", line 222, in run
2026-06-25 11:18:48.771 result = self._run(parsed_args, **kwargs) or result
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_application/commands/remote.py", line 162, in _run
2026-06-25 11:18:48.771 builds = builder.start_builds(project_dir, **build_args)
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_application/services/remotebuild.py", line 133, in start_builds
2026-06-25 11:18:48.771 _, self._repository = self._ensure_repository(project_dir)
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_application/services/remotebuild.py", line 278, in _ensure_repository
2026-06-25 11:18:48.771 work_tree.init_repo()
2026-06-25 11:18:48.771 File "/snap/snapcraft/18124/lib/python3.12/site-packages/craft_application/remote/worktree.py", line 54, in init_repo
2026-06-25 11:18:48.771 copytree(self._project_dir, self._repo_dir)
2026-06-25 11:18:48.771 File "/snap/snapcraft/current/usr/lib/python3.12/shutil.py", line 600, in copytree
2026-06-25 11:18:48.771 return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
2026-06-25 11:18:48.771 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-06-25 11:18:48.771 File "/snap/snapcraft/current/usr/lib/python3.12/shutil.py", line 554, in _copytree
2026-06-25 11:18:48.771 raise Error(errors)
2026-06-25 11:18:48.771 shutil.Error: [('/home/imani/work/scratch/here', '/home/imani/.cache/snapcraft/remote-build/snapcraft-scratch-a22566aae87cb46312173f84fc845a49/repo/here', "[Errno 2] No such file or directory: '/home/imani/work/scratch/here'")]
2026-06-25 11:18:48.771 Full execution log: '/home/imani/.local/state/snapcraft/log/snapcraft-20260625-111842.312392.log'
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| qwen/qwen3.6-35b-a3b | — | — | Closed without resolution. Remote-build crashes during project directory copying when dangling symlinks are present, causing a shutil.Error. No fix or follow-up was provided. | |
| qwen3.6-35b-a3b-mtp-q6 |
Impact:
50
Quick Win:
42.5
Staleness:
65
Complexity:
15
Confidence:
70
Support Request:
0
|
needs triage | Remote build fails on dangling symlinks due to copytree not handling them. Issue has no maintainer response or labels after 71 days. Related PR #1100 was closed without merging. | |
| qwen/qwen3.6-35b-a3b |
Staleness:
40
Complexity:
30
Confidence:
90
Support Request:
0
|
needs triage | Remote build fails with shutil.Error when project contains dangling symlinks. Reported by maintainer 26 days ago with clear reproduction steps and traceback, but currently unlabelled and awaiting triage. | |
| qwen3.6-35b-a3b-mtp-q6 |
Staleness:
40
Complexity:
35
Confidence:
95
Support Request:
5
|
needs triage | remote-build fails when copying project directories containing dangling symlinks, raising a shutil.Error during repository initialization. Unlabelled, 14 days old, awaiting maintainer triage. | |
| qwen3.6-35b-a3b-mtp-q6 |
Staleness:
5
Complexity:
30
Confidence:
90
Support Request:
5
|
needs triage | Remote build fails on dangling symlinks due to shutil.copytree error during repository preparation. Issue is fresh, unlabelled, and awaiting maintainer triage. |
Update history
| Date | Change |
|---|---|
| closed |
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #721 Don't follow symlinks for remote-builds | craft-application | open | Remote builds copy the project dir via copytree without symlinks=True, so symlinks are followed and failures surface as internal errors. Fix still unimplemented in worktree.py; triaged enhancement, still referenced by open snapcraft#5384. | |
| #1100 fix(remotebuild): allow building projects with dangling symlinks | craft-application | closed | Superseded by an alternative PR. The author closed this dangling symlink fix without merging, opting for @bepri's approach to avoid unmocking tests and unnecessary refactoring. | |
| #1744921 parent-relative symlinks error with sshfs | snapcraft (launchpad) | closed | Abandoned and closed without resolution. Reported a shutil.Error when snapcraft copied parent-relative symlinks during sshfs-based builds. No fix was implemented. |