Matched signals
- Too many levels of symbolic links
- dangling symlink
- broken symlink
- symlink.*not found
- readlink: Invalid argument
- ln: failed to create symbolic link
- symbolic link loop
- ELOOP
Symlink resolution failure in CI
What this failure means
A symlink in the repository or the build workspace is broken or cannot be
resolved in the CI environment. Common causes include symlinks pointing to
absolute paths that only exist on a developer’s machine, or symlinks that
survive a git clone but point to targets that are not checked out.
Symptoms
Faultline looks for one or more of these log fragments:
Too many levels of symbolic links
dangling symlink
broken symlink
symlink.*not found
readlink: Invalid argument
ln: failed to create symbolic link
symbolic link loop
ELOOP
Diagnosis
Symlinks behave differently across operating systems and CI environments:
- Absolute symlinks (e.g.,
/Users/dev/project/lib) break on any other machine - Symlinks inside a shallow clone may point to commits or paths not present
- Windows CI runners may not support symlinks without Developer Mode enabled
- Docker
COPYwith some configurations does not preserve symlinks
Find broken symlinks:
# List all symlinks
find . -type l | head -20
# Find broken symlinks (dangling)
find . -xtype l 2>/dev/null
# Show what each symlink points to
find . -type l -exec ls -la {} \;
Fix steps
-
Replace absolute symlinks with relative ones:
# Remove the absolute symlink rm path/to/broken-link # Re-create as relative ln -sr actual/target path/to/broken-link # or manually: ln -s ../actual/target path/to/broken-link -
If the symlink target is in
.gitignore, either:- Move the target into a tracked location, or
- Replace the symlink with a real file or a build step
-
Verify symlinks are committed correctly in git:
git ls-files -s | grep "^120000" # shows symlinks in index -
For Windows CI runners that do not support symlinks, replace them with file copies or use
git config core.symlinks trueat job start:- name: Enable symlinks run: git config --global core.symlinks true if: runner.os == 'Windows' -
In Docker, use
COPY --follow-link(BuildKit) to dereference symlinks during the build context transfer, or copy the target directly.
Validation
- Run
find . -xtype land confirm it produces no output. - Re-run the failing CI step.
Why it matters
Symlink failures produce obscure “file not found” errors that are hard to attribute to a symlink problem. They frequently work on macOS (case-insensitive filesystem) but break on Linux CI runners, creating a local-passes-CI-fails pattern.
Prevention
- Prefer relative symlinks over absolute ones.
- Add a CI lint step:
find . -xtype l— exit non-zero on dangling symlinks. - Document any symlinks in the README.
How Faultline detects it
Use faultline explain symlink-in-ci to see the full playbook.
faultline analyze build.log
faultline explain symlink-in-ci
Generated from playbooks/bundled/log/build/symlink-in-ci.yaml. Do not edit directly.