can1357/oh-my-pi · error · ToolError
Unknown skill: ${rawSkillSegment}. Available: ${availableStr
Error message
Unknown skill: ${rawSkillSegment}. Available: ${availableStr} What it means
The skill name inside the skill:// URL did not match any registered skill. matchSkillName compares the (decoded, suffix-stripped) segment against known Skill names; on no match the error lists every available name so the caller can self-correct. Namespaced names like "plugin:skill" and colon line-range suffixes like ":1-5" are handled during matching.
Source
Thrown at packages/coding-agent/src/tools/bash-skill-urls.ts:77
let rawSkillSegment = parsed[1];
if (!rawSkillSegment) {
throw new ToolError(`skill:// URL requires a skill name: ${url}`);
}
// Decode percent-encoded colons (%3A) used for namespaced skill names
try {
rawSkillSegment = decodeURIComponent(rawSkillSegment);
} catch {
// Leave as-is if decoding fails
}
// Resolve skill name by longest-prefix match against registered skills.
// This handles namespaced skills ("plugin:skill") where the URI may also
// carry a colon-delimited suffix (e.g., ":1-5" line range).
const { skill, suffix } = matchSkillName(rawSkillSegment, skills);
if (!skill) {
const available = skills.map(s => s.name);
const availableStr = available.length > 0 ? available.join(", ") : "none";
throw new ToolError(`Unknown skill: ${rawSkillSegment}. Available: ${availableStr}`);
}
// Combine any colon suffix (line range like ":1-5") with the path segment
const rawPath = (parsed[2] ?? "") + (suffix ? `/${suffix}` : "");
const hasRelativePath = rawPath !== "" && rawPath !== "/";
if (!hasRelativePath) {
return path.resolve(skill.baseDir);
}
let relativePath: string;
try {
relativePath = decodeURIComponent(rawPath.slice(1));
} catch {
throw new ToolError(`Invalid skill:// URL path encoding: ${url}`);
}
try {
validateRelativePath(relativePath);View on GitHub (pinned to 9690622007)
Solutions
- Use exactly one of the names listed in the error's "Available: ..." list.
- Confirm the skill/plugin is actually loaded and enabled before referencing it.
- If namespaced, include the full "plugin:skill" name (URL-encode the colon as %3A if needed).
- Re-fetch the current skill list — the registry may have changed since the URL was built.
Example fix
// before
resolveSkillUrlToPath("skill://code-review/SKILL.md", skills);
// Unknown skill: code-review. Available: plugin:review
// after
resolveSkillUrlToPath("skill://plugin%3Areview/SKILL.md", skills); Defensive patterns
Strategy: validation
Validate before calling
const name = decodeURIComponentSafe(nameSegment);
if (!skills.some(s => s.name === name)) {
throw new Error(`unknown skill '${name}'; available: ${skills.map(s => s.name).join(", ")}`);
} Try / catch
try {
return resolveSkillUrlToPath(url, skills);
} catch (e) {
if (e instanceof ToolError && e.message.startsWith("Unknown skill")) {
// parse 'Available:' list, pick closest match or report options to the user
} else throw e;
} Prevention
- Always source skill names from the live registry, not memory or hardcoded lists.
- Fuzzy-match the requested name against skills before resolving and suggest corrections.
- Re-check plugin load state when a previously working URL starts failing.
When it happens
Trigger: Calling resolveSkillUrlToPath("skill://typo-name/SKILL.md", skills) where "typo-name" matches no skill in the passed Skill[] — name misspelled, skill not loaded, wrong namespace prefix (missing "plugin:"), or a stale name after a plugin rename.
Common situations: A model invents a skill name; the user renamed or uninstalled a plugin skill; the skills array passed to the resolver is empty or filtered so a legitimately loaded skill looks unknown; colon-in-name edge cases where the suffix stripper eats part of the name.
Related errors
- skill:// URL requires a skill name: skill://<name>
- Invalid skill:// URL: ${url}
- skill:// URL requires a skill name: ${url}
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/86defee42556dfc1.
Report an issue: GitHub.