pbakaus/impeccable · error
Nothing was linked: {} had no variants for {}.
Error message
Nothing was linked: {} had no variants for {}. What it means
Report in link after link_provider_skills linked and skipped nothing: the resolved source checkout's bundle directory contained no per-provider variants for any of the selected targets. Usually means --source points at a checkout that has not been built (dist/ absent) or the provider names don't match the bundle layout.
Source
Thrown at crates/skills/src/commands.rs:494
let ans = prompt.ask(io, &format!("Link impeccable skills into {} folder(s)? (Y/n) ", targets.len()))?;
if ans == "n" || ans == "no" {
out(io, "Aborted. Re-run with --providers=<names> to choose explicitly (e.g. --providers=claude,cursor).");
return Err(Flow::Exit(0));
}
}
let result = bundle::link_provider_skills(io, &source.bundle_root, &root, &targets, force).map_err(Flow::Throw)?;
// Linked installs are excluded from install/update refreshes (overwriting
// a symlink would destroy the link), so this is the only path that can
// deliver the OpenCode command bridge to them. A copy, not a symlink: the
// bridge is static and OpenCode scans the real commands dir. No-ops when
// the source checkout has no built commands (#483).
bundle::copy_provider_commands(&sys, &source.bundle_root, &root, &targets, Some(Scope::Project));
if result.linked == 0 && result.already == 0 {
if result.skipped > 0 {
err(io, "Nothing was linked because matching skill folders already exist.");
err(io, "Existing skills were left untouched. Re-run with --force to replace them with links.");
} else {
err(io, &format!("Nothing was linked: {} had no variants for {}.", source.bundle_root, targets.join(", ")));
}
return Err(Flow::Exit(1));
}
// Linked skill dirs resolve into the source checkout; repair the
// launcher/binary executable bit there too (through the symlink), so a
// checkout whose copier dropped modes still runs.
for provider in &targets {
let skills_dir = util::jsp::join(&[&root, provider, "skills"]);
for skill in util::read_dir_names(&skills_dir).unwrap_or_default() {
let dir = util::jsp::join(&[&skills_dir, &skill]);
if util::is_dir(&dir) {
crate::engine_binary::ensure_executable_scripts(&dir);
}
}
}
let mut parts = Vec::new();
if result.linked > 0 {
parts.push(format!("{} linked", result.linked));View on GitHub (pinned to 2bc2879276)
Solutions
- Verify provider names against the bundle contents
- Rebuild the bundle with `bun run build`
- Check that `source.bundle_root` contains the expected skill folders
Example fix
// before impeccable link --providers=claude,codex-custom // after impeccable link --providers=claude,cursor
Defensive patterns
Strategy: validation
Validate before calling
const variants = fs.readdirSync(bundleRoot).filter(d => providers.includes(d));
if (variants.length === 0) console.error('No bundle variants for chosen providers'); Try / catch
try { await link(); } catch (e) { if (/had no variants/.test(String(e))) { console.error('Rebuild bundle or fix provider names'); } } Prevention
- Rebuild the bundle after pulling changes
- Only use provider names that exist in the bundle
- Verify bundle contents before linking
When it happens
Trigger: Running `impeccable link` with provider names that the built bundle does not contain variants for, or linking against an empty/unbuilt bundle root.
Common situations: Typos in `--providers`, a stale or partial build, or custom provider names the bundle doesn't ship.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- {e} (dynamic error string from bundle::resolve_link_source)
- Could not determine a target harness folder.
- Pass one explicitly, e.g. --providers=claude,cursor
- Nothing was linked because matching skill folders already ex
- Existing skills were left untouched. Re-run with --force to
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/4cd20e7297bc6286.
Report an issue: GitHub.