{"record":{"id":"57070e1f250a53fe","repo":"garrytan/gstack","slug":"skill-name-not-found-in-any-tier","errorCode":null,"errorMessage":"Skill \"${name}\" not found in any tier.","messagePattern":"Skill \"(.+?)\" not found in any tier\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browse/src/browser-skill-commands.ts","lineNumber":115,"sourceCode":"      [\n        s.name.padEnd(30),\n        s.tier.padEnd(8),\n        s.frontmatter.host.padEnd(28),\n        desc,\n      ].join(' '),\n    );\n  }\n  return lines.join('\\n') + '\\n';\n}\n\n// ─── show ───────────────────────────────────────────────────────\n\nfunction handleShow(args: string[], ctx: SkillCommandContext): string {\n  const name = args[0];\n  if (!name) throw new Error('Usage: $B skill show <name>');\n  const tiers = ctx.tiers ?? defaultTierPaths();\n  const skill = readBrowserSkill(name, tiers);\n  if (!skill) throw new Error(`Skill \"${name}\" not found in any tier.`);\n  return readFile(path.join(skill.dir, 'SKILL.md'));\n}\n\nfunction readFile(p: string): string {\n  return fs.readFileSync(p, 'utf-8');\n}\n\n// ─── run ────────────────────────────────────────────────────────\n\ninterface ParsedRunArgs {\n  passthrough: string[];\n  timeoutSeconds: number;\n}\n\nexport function parseSkillRunArgs(args: string[]): ParsedRunArgs {\n  const passthrough: string[] = [];\n  let timeoutSeconds = DEFAULT_TIMEOUT_SECONDS;\n  for (let i = 0; i < args.length; i++) {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/browser-skill-commands.ts#L97-L133","documentation":"Thrown by handleShow after readBrowserSkill walked all three tiers (project > global > bundled) and found no skill directory whose SKILL.md exists and parses cleanly. readBrowserSkill returns null on miss OR on a malformed SKILL.md (parse failure is swallowed and the next tier is tried), so this error can also mask a skill whose SKILL.md is invalid in every tier where the name exists.","triggerScenarios":"handleShow with a name that does not match any directory under <project>/.gstack/browser-skills/, ~/.gstack/browser-skills/, or <install>/browser-skills/. Also triggered when the only matching directory lacks a SKILL.md or has one that fails parseSkillFile (missing required `host` field, unparseable frontmatter).","commonSituations":"Typo in the skill name; skill was tombstoned (moved to .tombstones/); running outside a project so the project tier is null and only global/bundled are visible; SKILL.md was hand-edited and now missing the required `host` field; bundled install path shifted after a gstack upgrade.","solutions":["Run `$B skill list` to confirm the exact name and tier.","Check the project tier is being detected: run inside a git repo so detectProjectRoot resolves, or pass ctx.tiers explicitly.","Inspect ~/.gstack/browser-skills/<name>/SKILL.md and the bundled dir for frontmatter validity (must have `name` and `host`).","If tombstoned, look under <tier>/.tombstones/<name>-<ts>/ and move it back."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { listBrowserSkills, defaultTierPaths } from './browser-skills';\n\nfunction ensureSkillExists(name: string, tiers = defaultTierPaths()): void {\n  const known = new Set(listBrowserSkills(tiers).map(s => s.name));\n  if (!known.has(name)) {\n    throw new Error(`Skill \"${name}\" not found. Available: ${[...known].join(', ') || '(none)'}`);\n  }\n}\n// before handleShow:\nensureSkillExists(name);","typeGuard":"import type { BrowserSkill } from './browser-skills';\nconst isBrowserSkill = (x: unknown): x is BrowserSkill =>\n  typeof x === 'object' && x !== null && typeof (x as any).name === 'string' && typeof (x as any).dir === 'string';","tryCatchPattern":null,"preventionTips":["Cache `$B skill list` output and validate names against it before show/run/test.","When running outside a project, expect the project tier to be null — only global/bundled are visible.","Inspect <tier>/.tombstones/ if a previously-working skill suddenly 404s."],"tags":["skill-management","filesystem","gstack","browser-skills"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}