mastra-ai/mastra · warning · HTTPException

Skill name is required

Error message

Skill name is required

What it means

The get-skill-details handler (GET /workspaces/:workspaceId/skills/:skillName) throws this 400 when the `skillName` path parameter is missing/empty. The route contract requires a skill name to resolve the skill (optionally disambiguated via the ?path= query param). Practically this fires when the client requests a URL where the :skillName segment resolves to nothing.

Source

Thrown at packages/server/src/server/handlers/workspace.ts:957

  },
});

export const WORKSPACE_GET_SKILL_ROUTE = createRoute({
  method: 'GET',
  path: '/workspaces/:workspaceId/skills/:skillName',
  responseType: 'json',
  pathParamSchema: skillNamePathParams,
  queryParamSchema: skillDisambiguationQuerySchema,
  responseSchema: getSkillResponseSchema,
  summary: 'Get skill details',
  description: 'Returns the full details of a specific skill including instructions and file lists',
  tags: ['Workspace', 'Skills'],
  handler: async ({ mastra, skillName, path, workspaceId, requestContext }) => {
    try {
      requireWorkspaceV1Support();

      if (!skillName) {
        throw new HTTPException(400, { message: 'Skill name is required' });
      }

      // Use the optional ?path= query param for disambiguation, otherwise fall back to name
      const identifier = path ? decodeURIComponent(path) : skillName;

      const skills = await getSkillsById(mastra, workspaceId);
      if (!skills) {
        throw new HTTPException(404, { message: 'No workspace with skills configured' });
      }

      // Refresh skills with request context (handles dynamic skill resolvers)
      await skills.maybeRefresh({ requestContext });

      const skill = await skills.get(identifier);
      if (!skill) {
        throw new HTTPException(404, { message: `Skill "${identifier}" not found` });
      }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Request /workspaces/:workspaceId/skills/<skillName> with a real, non-empty skill name.
  2. URL-encode the skill name if it contains special characters.
  3. Fix client code interpolating an undefined variable into the path.
  4. If you don't know the name, list skills first via GET /workspaces/:id/skills.

Example fix

// before
const url = `/api/workspaces/ws1/skills/${name}`; // name === undefined
// after
const url = `/api/workspaces/ws1/skills/${encodeURIComponent('code-reviewer')}`;
Defensive patterns

Strategy: validation

Validate before calling

function assertSkillName(name: string | undefined): asserts name is string {
  if (!name) throw new Error('skillName must be provided before requesting skill details');
}

Type guard

function hasSkillName(n: unknown): n is string {
  return typeof n === 'string' && n.trim().length > 0;
}

Try / catch

try {
  const skill = await getSkill(wsId, name);
} catch (e) {
  if (isHTTPException(e, 400) && e.message === 'Skill name is required') {
    // fix URL construction; fall back to listing skills
  } else throw e;
}

Prevention

When it happens

Trigger: Requesting /workspaces/:id/skills/ (trailing slash, empty segment); a client template with an undefined skillName variable; proxy rewriting that drops the path segment; calling the underlying handler programmatically without skillName.

Common situations: URL builders that interpolate undefined names; encoded/empty names stripped by middleware; docs examples copy-pasted without substituting the skill name; redirects that lose the last path segment.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/5bb9bbd48d206a98. Report an issue: GitHub.