Skills loader ignores symlinked SKILL.md (breaks Nix/Home Manager installs)

Resolved 💬 2 comments Opened Feb 7, 2026 by denismaciel Closed Feb 7, 2026

What version of Codex CLI is running?

codex-cli 0.98.0 (codex --version)

What subscription do you have?

Unknown (CLI via API token).

Which model were you using?

gpt-5.3-codex (also reproduced with gpt-5.2-codex).

What platform is your computer?

Linux 6.12.68 x86_64 unknown (uname -mprs)

What terminal emulator and version are you using (if applicable)?

Reproduces in non-interactive codex exec; tmux in use: tmux 3.6a.

What issue are you seeing?

Skills whose SKILL.md is a symlink are not discovered/listed.

This breaks Nix/Home Manager style installs where user dotfiles (including skills) are symlinked into the Nix store (e.g. ~/.codex/skills/<name>/SKILL.md -> /nix/store/...).

What steps can reproduce the bug?

mkdir -p ~/.codex/skills/demo
printf '---\nname: demo\ndescription: demo skill\n---\n' > /tmp/demo-skill.md
ln -sf /tmp/demo-skill.md ~/.codex/skills/demo/SKILL.md

codex exec "which skills do you have access to"

What is the expected behavior?

demo should be listed as an available skill.

Additional information

If you replace the symlink with a regular file copy (cp -L ...), the skill is discovered.

Root cause in codex-rs/core/src/skills/loader.rs (discover_skills_under_root()):

  • When an entry is a symlink, it calls fs::metadata().
  • It only follows/enqueues the entry if metadata.is_dir().
  • Otherwise it continues, so symlinks to files (including SKILL.md) are skipped.

At commit a118494323a46c2e7181fb7b0a7c19178fba6578, this is around lines 393-425.

Suggested fix: in the symlink branch, if the symlink resolves to a file and file_name == "SKILL.md", call parse_skill_file(&path, scope) and push to outcome.skills (same error handling as the non-symlink is_file() path). parse_skill_file() already canonicalizes the path.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗