{"record":{"id":"73677879f9a67567","repo":"mastra-ai/mastra","slug":"no-content-available-for-skill-skillname","errorCode":null,"errorMessage":"No content available for skill \"${skillName}\"","messagePattern":"No content available for skill \"(.+?)\"","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"packages/server/src/server/handlers/skills-sh-shared.ts","lineNumber":240,"sourceCode":"    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 };\n  } finally {\n    clearTimeout(timeoutId);\n  }\n}\n\n/**\n * Fetch the full file tree for a skill from the skills.sh files endpoint.\n * Returns null when the skill doesn't exist (404). Throws on other upstream\n * errors. Caller is responsible for validating each returned file path with\n * `assertSafeFilePath` before writing to disk.\n */\nexport async function fetchSkillFiles(\n  owner: string,","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/skills-sh-shared.ts#L222-L258","documentation":"After a successful skills.sh response, previewSkillsSh extracts content from the JSON body (instructions or raw fields). If both are empty/missing, the skill technically exists but has no usable content, so the route throws HTTPException 404. This prevents returning an empty preview to the UI.","triggerScenarios":"Previewing a skill whose skills.sh content payload contains neither 'instructions' nor 'raw' (or both are empty strings); the upstream 200 response has no content fields.","commonSituations":"Skill published with an empty SKILL.md; skills.sh indexing a repo but failing to extract content; skill metadata present but content not yet generated; API schema change upstream.","solutions":["Verify the skill's SKILL.md/content is actually published on skills.sh","Re-publish or push the skill content to the source repo and let skills.sh re-index","If the API shape changed, update the data.instructions || data.raw extraction to match the new field names","Surface a 'skill has no content' state in the UI instead of an empty preview"],"exampleFix":"// before\nconst content = data.instructions || data.raw || '';\n// after (also check alternate fields)\nconst content = data.instructions || data.raw || data.content || '';","handlingStrategy":"fallback","validationCode":"// Can't be checked before the call; validate after receiving the payload\nconst hasContent = (d: { instructions?: string; raw?: string }) => Boolean(d.instructions || d.raw);","typeGuard":"function hasSkillContent(d: unknown): d is { instructions: string } | { raw: string } {\n  const o = d as any;\n  return typeof o === 'object' && o !== null && (typeof o.instructions === 'string' && o.instructions.length > 0 || typeof o.raw === 'string' && o.raw.length > 0);\n}","tryCatchPattern":"let preview;\ntry {\n  preview = await api.previewSkill(owner, repo, name);\n} catch (e) {\n  if (isEmptyContentError(e)) preview = { content: null, note: 'Skill published but has no content' };\n  else throw e;\n}","preventionTips":["Ensure SKILL.md/content is committed and pushed before publishing a skill","Render an explicit empty-content state in the preview UI","Spot-check the skills.sh payload shape when upgrading"],"tags":["http-404","empty-content","skills-api"],"backgroundTag":"empty-response-payload","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}