{"record":{"id":"c779cfdef5715a3c","repo":"pbakaus/impeccable","slug":"skipped-existing-provider-skills-skill-use","errorCode":null,"errorMessage":"Skipped existing {provider}/skills/{skill}. Use --force to replace it with a link.\n","messagePattern":"Skipped existing (.+?)/skills/(.+?)\\. Use --force to replace it with a link\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/skills/src/bundle.rs","lineNumber":855,"sourceCode":"        }\n        seen.push(real);\n        unique.push((provider, local_skills_dir));\n    }\n    for (provider, local_skills_dir) in unique {\n        let src_dir = jsp::join(&[bundle_root, provider, \"skills\"]);\n        if !util::exists(&src_dir) {\n            continue;\n        }\n        for skill in bundle_skill_dirs(&src_dir) {\n            let src = jsp::join(&[&src_dir, &skill]);\n            let dest = jsp::join(&[&local_skills_dir, &skill]);\n            if util::exists_or_link(&dest) {\n                if is_symlink_to(&dest, &src) {\n                    result.already += 1;\n                    continue;\n                }\n                if !force {\n                    io.err(&format!(\"Skipped existing {provider}/skills/{skill}. Use --force to replace it with a link.\\n\"));\n                    result.skipped += 1;\n                    continue;\n                }\n                util::rm_rf(&dest);\n            }\n            let mut target = jsp::relative(\"/\", &jsp::dirname(&dest), &src);\n            if target.is_empty() {\n                target = \".\".to_string();\n            }\n            util::symlink_dir(&target, &dest)?;\n            result.linked += 1;\n        }\n    }\n    Ok(result)\n}\n\n#[cfg(test)]\nmod tests {","sourceCodeStart":837,"sourceCodeEnd":873,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/skills/src/bundle.rs#L837-L873","documentation":"In `link_provider_skills`, when creating symlinks for provider skills, a destination that already exists blocks the operation. If the existing entry is not already a symlink to the intended source and `--force` was not passed, the skill is skipped with this message and counted in `result.skipped` — nothing is overwritten.","triggerScenarios":"Running `impeccable skills link` (without `--force`) where `<provider>/skills/<skill>` already exists as a regular directory/file, or as a symlink pointing somewhere other than the checkout source.","commonSituations":"A previous `skills install` copied the skill into the provider directory; a manually created folder with the same name; a stale symlink left from an old checkout path that no longer matches the new source.","solutions":["Re-run with `--force`: `impeccable skills link --force` to replace the existing entry with a link.","Manually remove the existing `<provider>/skills/<skill>` path, then link again.","If the existing copy is intentional and current, do nothing — the skip is safe.","If the existing path is a stale symlink to an old checkout, delete just that symlink and re-link."],"exampleFix":"// before\nimpeccable skills link   # Skipped existing claude/skills/impeccable\n// after\nimpeccable skills link --force\n","handlingStrategy":"validation","validationCode":"[ -e .claude/skills/impeccable ] && echo 'destination exists; pass --force or remove it first'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `skills link` with --force when you know prior installs exist.","Remove old copied skill directories before switching to linked installs.","Check for stale symlinks after moving the skill checkout."],"tags":["symlink","installation","already-exists","skills"],"backgroundTag":"file-already-exists","analyzedSha":"2bc2879276c1f321a53c4ca99d3371e411329b52","analyzedAt":"2026-09-08T04:51:14.109Z","contentChangedAt":"2026-09-08T04:51:14.109Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}