Codex CLI doesn’t load skills from .agents/skills when it is a symlink
Description
Codex CLI does not discover skills when .agents/skills is a symlink. Skills load correctly when .agents/skills is a real directory. This breaks workflows where .agents/skills points to another location.
Expected behavior
Codex should traverse .agents/skills even when it is a symlink, and load skills found under the target directory.
Actual behavior
When .agents/skills is a symlink, no skills are discovered. Replacing the symlink with a real directory makes the skills appear.
Steps to reproduce
1) Create a skills directory at skills-store/ containing skill folders with SKILL.md files.
2) Make .agents/skills a symlink to that directory:
ln -s skills-store .agents/skills
3) Start Codex in the repo and check the available skills list.
4) Observe that none of the skills under the symlink are loaded.
5) Replace the symlink with a real directory:
mv .agents/skills .agents/skills.symlink.bakmkdir -p .agents/skillscp -R skills-store/* .agents/skills/
6) Restart Codex and check skills again.
7) Skills are now discovered.
Environment
- Codex CLI version: v0.98.0
- OS: macOS (Darwin 25.2.0, arm64)
Workaround
Use a real .agents/skills directory (copy files instead of symlinking).
5 Comments
I'm not able to repro the problem. Codex does support symlinking the
/.agents/skillsdirectory (both global and per-project). I just verified that it works as expected with 0.98 on my system (also macOS).We recently added live updates for skills using file watcher events. Live updates won't work with a symlink, but you should be able to see any skills updates after relaunching the CLI.
I use v0.98.0 on macOS, and I have the same problem.
I test it by relaunching the CLI, but it still does not work.
@suhaibmujahid are you using the global skills path (
~/.agents/skills) or a project-relative path (<project-root>/.agents/skills)? I've tested both on my system and confirmed that the Codex code handles this. We even have unit tests in place for them.Are you using relative paths in your symlink? Can you verify that your symlink path is valid?
@etraut-openai no, it was not valid, which was the problem. Thank you for pointing that out.
In the context of the STR above, to make it work, the
.agents/skillssymlink should be created with a valid relative path:cd .agentsln -s ../skills-store ./skillsProposal: Improve Symlink Diagnostics in Skill Loader
Context
This proposal addresses Issue #11314 where broken symlinks for skill roots fail silently, making it difficult for users to debug skill loading issues.
Problem Analysis (What & Why?)
The current
discover_skills_under_rootfunction usescanonicalize_path(root). If this fails (common for broken symlinks), the function returns silently. This is a "fail-silent" behavior that hides configuration errors from the user. Since the CLI encourages using.agents/skills(which users often symlink), providing diagnostic feedback is critical for a smooth DX.Proposed Solution (How?)
The implementation adds explicit checks for symlink status when path resolution fails:
discover_skills_under_root, ifcanonicalize_pathfails, we perform afs::symlink_metadatacheck. If a symlink is present, we log atracing::warn!alerting the user to a broken/invalid root link.repo_agents_skill_rootsto catch invalid symlinks in the.agents/skillsproject hierarchy.tracing::warn!to ensure visibility in standard log streams while maintaining a non-breaking execution path (Codex will still load other valid skills).Verification
warns_on_broken_symlink_at_rootthat simulates a broken symlink and verifies the discovery path remains stable.