Some skills.sh skills fail to install because Houston can't locate their SKILL.md in the source repo. The marketplace then shows a "failed" pill without surfacing the real reason. Split off from #398 / PR #479 as a follow-up.
Repro
anthropics/claude-code → writing-hookify-rules → install fails with SkillError::SkillNotInRepo ("Couldn't find that skill in the repo. The author may have renamed or removed it.").
- Near-miss that currently works only thanks to fuzzy matching:
vercel/ai → ai-sdk actually lives at skills/use-ai-sdk/SKILL.md (directory use-ai-sdk ≠ skillId ai-sdk).
Root cause
houston_skills::remote::install_skill (engine/houston-skills/src/remote.rs) guesses the path from a small candidate list:
let candidates = [
format!("skills/{skill_id}/SKILL.md"),
format!("{skill_id}/SKILL.md"),
"SKILL.md".to_string(),
];
then falls back to find_skill_path_in_repo, which fetches the recursive git tree and matches by (a) derived directory name == skillId, (b) path containing skillId as a substring + frontmatter name: == skillId.
This misses when:
- The skill dir name doesn't match the skillId and isn't a substring (and frontmatter
name differs).
- The repo is large and the git tree is
truncated: true — some SKILL.md paths never appear in the response (e.g. anthropics/claude-code is enormous), so the scan can't find them.
- The skills.sh search result
id is owner/repo/<skillId> where <skillId> is only the directory name, not the real sub-path, so we can't fetch directly.
Secondary: error not surfaced
ui/skills/src/community-skills-browser.tsx handleInstall catches the failure and sets a per-skill "failed" state but does not toast errorMessage(err) with a Report-bug affordance — so the user sees "failed" with no reason. Same shape in add-skill-dialog-store-view.tsx. This is the no-silent-failures policy (CLAUDE.md) leaking.
Suggested directions
- Best: get the real
SKILL.md path from the skills.sh API (if it exposes it) and fetch it directly instead of guessing.
- Handle truncated trees: fetch subtrees lazily, or use the Git Contents/Search API to locate
SKILL.md.
- Broaden candidate conventions (
skills/, .claude/skills/, plugins/*/skills/, nested dirs).
- Surface the actual
SkillError reason in the marketplace (toast + Report bug), not just a silent "failed" pill.
References
Some skills.sh skills fail to install because Houston can't locate their
SKILL.mdin the source repo. The marketplace then shows a "failed" pill without surfacing the real reason. Split off from #398 / PR #479 as a follow-up.Repro
anthropics/claude-code→writing-hookify-rules→ install fails withSkillError::SkillNotInRepo("Couldn't find that skill in the repo. The author may have renamed or removed it.").vercel/ai→ai-sdkactually lives atskills/use-ai-sdk/SKILL.md(directoryuse-ai-sdk≠ skillIdai-sdk).Root cause
houston_skills::remote::install_skill(engine/houston-skills/src/remote.rs) guesses the path from a small candidate list:then falls back to
find_skill_path_in_repo, which fetches the recursive git tree and matches by (a) derived directory name == skillId, (b) path containing skillId as a substring + frontmattername:== skillId.This misses when:
namediffers).truncated: true— someSKILL.mdpaths never appear in the response (e.g.anthropics/claude-codeis enormous), so the scan can't find them.idisowner/repo/<skillId>where<skillId>is only the directory name, not the real sub-path, so we can't fetch directly.Secondary: error not surfaced
ui/skills/src/community-skills-browser.tsxhandleInstallcatches the failure and sets a per-skill"failed"state but does not toasterrorMessage(err)with a Report-bug affordance — so the user sees "failed" with no reason. Same shape inadd-skill-dialog-store-view.tsx. This is the no-silent-failures policy (CLAUDE.md) leaking.Suggested directions
SKILL.mdpath from the skills.sh API (if it exposes it) and fetch it directly instead of guessing.SKILL.md.skills/,.claude/skills/,plugins/*/skills/, nested dirs).SkillErrorreason in the marketplace (toast + Report bug), not just a silent "failed" pill.References
engine/houston-skills/src/remote.rs—install_skill,find_skill_path_in_repo,fetch_skill_md_at_pathui/skills/src/community-skills-browser.tsx—handleInstall(swallowed error)