{"record":{"id":"5fb835f8a31a0dfd","repo":"mastra-ai/mastra","slug":"could-not-find-skill-skillname-in-owner-5fb835","errorCode":null,"errorMessage":"Could not find skill \"${skillName}\" in ${owner}/${repo}.","messagePattern":"Could not find skill \"(.+?)\" in (.+?)/(.+?)\\.","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"packages/server/src/server/handlers/workspace.ts","lineNumber":1440,"sourceCode":"      requireWorkspaceV1Support();\n\n      const workspace = await getWorkspaceById(mastra, workspaceId);\n      if (!workspace) {\n        throw new HTTPException(404, { message: 'Workspace not found' });\n      }\n\n      if (!workspace.filesystem) {\n        throw new HTTPException(400, { message: 'Workspace filesystem not available' });\n      }\n\n      if (workspace.filesystem.readOnly) {\n        throw new HTTPException(403, { message: 'Workspace is read-only' });\n      }\n\n      // Fetch skill files from the Skills API\n      const result = await fetchSkillFiles(owner, repo, skillName);\n      if (!result || result.files.length === 0) {\n        throw new HTTPException(404, {\n          message: `Could not find skill \"${skillName}\" in ${owner}/${repo}.`,\n        });\n      }\n\n      // Validate skill name to prevent path traversal\n      const safeSkillId = assertSafeSkillName(result.skillId);\n      const installPath = buildSkillInstallPath(workspace.filesystem, safeSkillId, mount);\n\n      // Ensure the skills directory exists\n      try {\n        await workspace.filesystem.mkdir(installPath, { recursive: true });\n      } catch {\n        // Directory might already exist\n      }\n\n      // Write all files to the workspace\n      let filesWritten = 0;\n      for (const file of result.files) {","sourceCodeStart":1422,"sourceCodeEnd":1458,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/workspace.ts#L1422-L1458","documentation":"HTTPException 404 thrown after fetchSkillFiles returns null or a response with an empty files array, meaning the skill could not be located (or has no files) in the given owner/repo on skills.sh. Distinct from 3303: this is the multi-file install path.","triggerScenarios":"Calling the workspace install-skill route with an owner/repo/skillName whose files listing yields no files — wrong slug, unpublished skill, or private repo.","commonSituations":"Typos in skill or repo names; skill moved to another repo; skills.sh indexing lag for freshly published skills; repo made private after the skill was referenced.","solutions":["Verify the skill exists with files at skills.sh for that exact owner/repo slug.","Check the repo is public/accessible to the upstream API.","Retry shortly after publishing if the skill is new (indexing delay), or fall back to installing files fetched directly from the repository."],"exampleFix":"// before\nawait installSkill({ workspaceId, owner: 'acme', repo: 'widgets', skillName: 'deploy' });\n// after\nawait installSkill({ workspaceId, owner: 'acme', repo: 'widget-skills', skillName: 'deploy' }); // correct repo","handlingStrategy":"try-catch","validationCode":"// Verify the skill resolves (non-empty file list) before installing\nconst listing = await fetchSkillFiles(owner, repo, skillName).catch(() => null);\nif (!listing || listing.files.length === 0) throw new Error(`Skill ${skillName} not found in ${owner}/${repo}`);","typeGuard":"function isSkillListing(r: unknown): r is { skillId: string; files: unknown[] } {\n  const o = r as any;\n  return !!o && typeof o.skillId === 'string' && Array.isArray(o.files);\n}","tryCatchPattern":"try {\n  await installSkill({ workspaceId, owner, repo, skillName });\n} catch (e) {\n  if (new RegExp(`Could not find skill \"${skillName}\"`).test(String(e))) {\n    console.warn('Skill not found; verify the slug on skills.sh.');\n    return { installed: false };\n  }\n  throw e;\n}","preventionTips":["Validate owner/repo/skillName against the registry listing before install.","Allow retry-with-delay for freshly published skills (indexing lag).","Provide a direct-from-repo fallback install path when the registry listing is empty."],"tags":["http-404","not-found","upstream-api","skills","workspace"],"backgroundTag":"skill-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}