{"record":{"id":"269b02981f2d09c7","repo":"mastra-ai/mastra","slug":"could-not-find-skill-skillname-for-owner","errorCode":null,"errorMessage":"Could not find skill \"${skillName}\" for ${owner}/${repo}","messagePattern":"Could not find skill \"(.+?)\" for (.+?)/(.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"packages/server/src/server/handlers/skills-sh-shared.ts","lineNumber":227,"sourceCode":"export async function previewSkillsSh({\n  owner,\n  repo,\n  skillName,\n}: {\n  owner: string;\n  repo: string;\n  skillName: string;\n}): Promise<{ content: string }> {\n  const controller = new AbortController();\n  const timeoutId = setTimeout(() => controller.abort(), PREVIEW_TIMEOUT_MS);\n\n  try {\n    const url = `${SKILLS_SH_API_URL}/api/skills/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/${encodeURIComponent(skillName)}/content`;\n    const response = await fetch(url, { signal: controller.signal });\n\n    if (!response.ok) {\n      if (response.status === 404) {\n        throw new HTTPException(404, {\n          message: `Could not find skill \"${skillName}\" for ${owner}/${repo}`,\n        });\n      }\n      throw new HTTPException(502, {\n        message: `Skills API error: ${response.status} ${response.statusText}`,\n      });\n    }\n\n    const data = (await response.json()) as { instructions?: string; raw?: string };\n    const content = data.instructions || data.raw || '';\n\n    if (!content) {\n      throw new HTTPException(404, {\n        message: `No content available for skill \"${skillName}\"`,\n      });\n    }\n\n    return { content };","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/skills-sh-shared.ts#L209-L245","documentation":"previewSkillsSh proxies the skills.sh API to preview a skill's content before it's installed. When the upstream skills.sh API responds 404 — meaning no skill exists at owner/repo/skillName — the route translates that into its own HTTPException 404. The library throws this to distinguish 'skill not found' from a generic upstream failure.","triggerScenarios":"Calling the registry preview route (BUILDER_REGISTRY_PREVIEW_ROUTE) with an owner/repo/skillName triple that doesn't exist on skills.sh; the upstream GET /api/skills/{owner}/{repo}/{skillName}/content returns status 404.","commonSituations":"Typo in skillName, owner, or repo; skill renamed or deleted upstream; previewing a private/unlisted skill that skills.sh doesn't expose; stale bookmark/URL pointing to a removed skill.","solutions":["Verify the skill exists by checking the skills.sh page for that owner/repo/skillName","Fix typos in owner, repo, or skillName in the request path/params","Use encodeURIComponent-safe exact names (case sensitivity matters)","Handle 404 in the client UI with a 'skill not found' message instead of retrying"],"exampleFix":"// before\npreview({ owner: 'acme', repo: 'utils', skillName: 'code-review' })\n// after (verify name first, then handle 404)\nconst res = await fetch('/api/registry/preview?owner=acme&repo=utils&skillName=code-reviewer');\nif (res.status === 404) showNotFound();","handlingStrategy":"try-catch","validationCode":"const exists = await fetch(`https://skills.sh/api/skills/${owner}/${repo}/${skillName}/content`, { method: 'HEAD' }).then(r => r.status !== 404).catch(() => false);\nif (!exists) throw new Error(`Skill ${skillName} not found on skills.sh`);","typeGuard":"function isNotFoundResponse(e: unknown): e is { status: 404 } {\n  return typeof e === 'object' && e !== null && 'status' in e && (e as any).status === 404;\n}","tryCatchPattern":"try {\n  const preview = await api.previewSkill(owner, repo, skillName);\n} catch (e) {\n  if (isNotFoundResponse(e)) showNotFound(owner, repo, skillName);\n  else throw e;\n}","preventionTips":["Validate skill names against the skills.sh registry before previewing","Copy owner/repo/skillName directly from the skills.sh URL to avoid typos","Treat 404 as a terminal state — do not retry"],"tags":["http-404","skills-api","not-found"],"backgroundTag":"upstream-resource-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}