skillmirror
Reference

بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ

Troubleshooting

The messages you are most likely to meet, what each one means, and the shortest way to fix it.

skillmirror stops with a message and, nearly always, a hint under it. This page goes through the ones you are most likely to meet. When you are not sure where to start, run skillmirror doctor: it checks the machine, the configuration, the vault and every SKILL.md header, and it writes nothing.

It cannot find its configuration

No vault configured

Nothing tells skillmirror where your vault is. The pointer file does not exist, SKILLMIRROR_VAULT is not set, and you passed no --vault.

skillmirror status
error: no vault configured
hint: pass --vault, set SKILLMIRROR_VAULT, or run the setup wizard

Make a vault with skillmirror vault init ~/skills --root ~/projects, or point at one you have by writing its path into ~/.config/skillmirror/vault. skillmirror with no arguments opens the interface, whose Setup entry does the same (Configuration). A missing scan root is the same kind of message, error: no scan root configured, and the fix is skillmirror config root DIR.

Legacy environment variables are set

The Go tool skill_Manag read variables that start with SKILL_MANAG_. skillmirror refuses them, because ignoring one could sync the wrong vault. The hint names the replacement:

SKILL_MANAG_VAULT=~/skills skillmirror status
error: legacy environment variables are set: SKILL_MANAG_VAULT
hint: rename each variable: SKILL_MANAG_VAULT -> SKILLMIRROR_VAULT

SKILL_MANAG_ROOT becomes SKILLMIRROR_ROOT. Change it in your shell startup file, and open a new terminal. The exit code is 3.

Old configuration found

The pointer file of the old tool exists, and the new one does not:

skillmirror status
error: old configuration found at ~/.config/skill_Manag/vault and none at ~/.config/skillmirror/vault
hint: run `skillmirror migrate`

migrate copies the pointer and keeps the old file, and --retire removes the old one afterwards, so that the old tool stops finding the vault:

skillmirror migrate
Copied the vault pointer to ~/.config/skillmirror/vault
Vault: ~/skills
The old pointer ~/.config/skill_Manag/vault is kept; run `skillmirror migrate --retire` to remove it

The config file is refused

config.yaml has a key skillmirror does not know. The message points at the line and lists the keys that exist:

skillmirror status
error: invalid vault config ~/skills/config.yaml: error: line 12 column 1: unknown field `colour`, expected one of root, mandatory, exclude_dirs, exclude_paths, profiles, targets, web
  --> <input>:12:1
   |
10 |     skills: [coding]
11 | web: false
12 | colour: blue
   | ^ unknown field `colour`, expected one of root, mandatory, exclude_dirs, exclude_paths, profiles, targets, web

Fix the key, or remove it. A value that breaks a rule gets a message of its own, for example targets entry "cursor" is not a known agent folder (known: claude) (Configuration).

The scan root does not exist

skillmirror --root ~/nosuchfolder status
error: scan root ~/nosuchfolder does not exist
hint: pass --root, set SKILLMIRROR_ROOT, or fix `root:` in <vault>/config.yaml

An exclude_paths entry does not exist

Every command that scans stops until the entry is fixed or removed, because a path that matches nothing would exclude nothing, and you would not know:

error: exclude_paths entry ~/projects/atlas-api/testdta does not exist
hint: fix or remove the entry in <vault>/config.yaml; a path that matches nothing excludes nothing

Look for a typo, or for a folder that has moved since you wrote the entry (Skipping folders).

A project or a skill is not where you expect

A project is not listed

skillmirror list shows every skill folder the scan found, and status --all shows every project. A project is found when all of this holds:

  • It is below the scan root (skillmirror config show prints the root).
  • It has a .agents/skills folder. A link in its place is not followed.
  • No folder above it is skipped: not one of the built-in names such as node_modules or dist, and not one of your exclude_dirs or exclude_paths.

skillmirror doctor names the folders the scan could not read, and prints them under scan.

A folder is marked as not in the vault

A project has a skill folder the vault has no skill for. status marks it with ?, and list writes (not in vault). A sync leaves it alone. If it is a skill you want to keep, skillmirror adopt NAME --from PROJECT copies it into the vault (Improve a skill).

Several projects are below this folder

changes and promote work on one project. They start in the folder you are in and go up, and they stop after the top of its git repository. When they find none, they look below:

cd ~ && skillmirror changes
error: 4 projects are below ~: ~/projects/atlas-api, ~/projects/docs-site, ~/projects/infra, ~/projects/lumen-app
hint: pass --project DIR to pick one, or start in it

The exit code is 2. cd into the project, or pass --project DIR.

A sync does not do what you expect

A skill has no git-tracked files in the vault

The vault copies what git tracks. A skill whose SKILL.md is not tracked is refused for every project, and the other skills still go through:

skillmirror sync --dry-run
● ~/projects/docs-site
  ✗ astro                          skill "astro" has no git-tracked files in the vault
      hint: run `git add` for astro in the vault and commit

● ~/projects/infra
  ✗ astro                          skill "astro" has no git-tracked files in the vault
      hint: run `git add` for astro in the vault and commit

● ~/projects/lumen-app
  ✗ astro                          skill "astro" has no git-tracked files in the vault
      hint: run `git add` for astro in the vault and commit

13 skills in 4 projects: 10 up to date, 3 failed (dry run)

The exit code is 4. doctor finds the cause before a sync does, and says it twice, as an error and as a warning about the files next to it:

✗ skill-files astro: SKILL.md is not tracked by git, so sync refuses this skill
    hint: `git add` it in the vault and commit
! skill-edits astro: 1 new file(s) are not tracked by git and are not copied
    hint: `git add` them in the vault

Run git add for the skill in the vault. A commit is not needed for the copy: a staged file travels, and a skill you edited and did not commit travels as well, with a note from doctor that says so. You commit when the skill is ready (Files and folders).

A file does not arrive in the projects

The same rule, one file at a time. info lists the files that are copied and the ones git does not track:

  files        2 copied
    SKILL.md
    references/naming.md
  not copied   1 file (git does not track it)
    draft.md

git add the file in the vault, and the next sync brings it.

Refusing to write without confirmation

A command that writes asks first, and nobody is there to ask: stdin is not a terminal, as in a script or a pipe. Nothing was written. Pass --yes to apply, or --dry-run to look (Scripts and CI).

error: refusing to write without confirmation
hint: pass --yes to apply, or --dry-run to preview

A sync replaced an edit

A project copy that you edited differs from the vault, and a sync makes it equal again. skillmirror undo brings the edit back, because every replaced folder went to the backup first (Safety and undo). Next time, run changes in the project before you sync, and promote what you want to keep.

promote refuses

Two refusals are common, and each has its own hint:

error: "coding" is not promoted: it equals the vault's copy
hint: `skillmirror changes` shows the state of every skill of the project
error: "coding" has changes in the vault that are not staged (coding/SKILL.md), a promote would replace them
hint: commit or discard those changes in the vault first, or work from them

The first says there is nothing to promote. The second protects an edit you made in the vault: commit it, or discard it, and promote again.

An AGENTS.md block was edited by hand

agents sync stops for that project and writes nothing. Move your lines below the block, or replace the block with --force after you read what would go (AGENTS.md for every project).

  ✗ ~/projects/atlas-api failed: the autogenerated block was edited by hand; --force replaces it (the old file is kept for `undo`)

What doctor can tell you

A SKILL.md header is not valid

Agents read the name and the description from the header of SKILL.md. doctor checks that it parses, and that the name is the folder's name:

! skill-files badheader: the header is not valid YAML: line 2 column 20: mapping values are not allowed in this context
    hint: agents read name and description from the header; quote a value that contains a colon
! skill-files wrongname: the header says name "other", the folder is called "wrongname"

A profile names a group the vault does not have

✗ profiles websites: group "Web_Skills" is not a folder of the vault
    hint: `skillmirror skills` shows the groups

A path that you moved changes the name of the group. Fix groups: of the profile, because --group and groups: take folder paths, and a skill name is not affected by a move (Configuration).

A leftover of an interrupted run

! leftovers ~/projects/infra/.agents/.stage-4294967000-abc-0: left over from an interrupted run; delete it by hand

A run that was killed left its temporary folder behind. Look at it, then delete it (Files and folders).

The scan root is on a filesystem that cannot swap folders

A skill folder is replaced by swapping two folders in one step (renameat2). Some filesystems cannot do that: NFS, CIFS, FUSE and FAT. doctor names the one it found, as a warning (<root> stands for your scan root, and the kind of filesystem changes):

! filesystem <root>: the scan root is on a FUSE filesystem, which may not support swapping a folder atomically (renameat2); writes into projects there would fail
    hint: keep the projects on a local filesystem such as ext4, xfs or btrfs

Reading works there, and writing into a project would fail.

A bridge is missing, or a real folder is in the way

doctor and status tell you when targets: asks for .claude/skills and the link is not there. skillmirror bridge makes it, and a real folder in the way has a message of its own (Other agent folders).

Other messages

The web view does not start

The web view needs two things, a build that has it and web: true in the config. skillmirror web says which one is missing:

skillmirror web
error: the web view is switched off in the config, and this build of skillmirror has no web view
hint: turn it on with `skillmirror config web on` (sets `web: true` in ~/skills/config.yaml); build it in with `cargo install --path Crates/Cli --locked --features web` (or `just install-web`)

The exit code is 2 (The web view).

init stops before it makes anything

init checks everything first. It refuses a folder that is not empty (error: ~/projects/lumen-app is not empty, with a hint to use add), a selection that is empty (error: nothing selected), and a scaffold that its skill cannot make (error: the project scaffold is made by the script of the doc-start skill, and doc-start is not among the skills this install gives the project). Each has a hint, and Start a project shows them.

Unknown command or option

A misspelled command or option is a syntax error with exit code 2, and the message suggests the nearest one:

skillmirror completions nosuchshell
error: invalid value 'nosuchshell' for '<SHELL>'
  [possible values: bash, elvish, fish, powershell, zsh]

  tip: a similar value exists: 'powershell'

For more information, try '--help'.

There is no backup to restore, or no such run

undo brings back a run from history. Only runs that replaced or removed something leave a backup, and the newest 30 are kept. A run id that is not in the list is an error with exit code 2:

skillmirror undo 20200101-000000-000-0-0 --yes
error: no backup run named "20200101-000000-000-0-0"
hint: `skillmirror history` lists the runs

Still stuck

Run skillmirror doctor --json and read the findings: each has the check, the subject, the message and the hint. The issue tracker is the place for what this page does not explain, and a report with the exact message, the version from skillmirror --version, and the output of doctor gets answered fastest.

On this page