mastra-ai/mastra · error · HTTPException
Invalid skill name "${name}". Names must start with alphanum
Error message
Invalid skill name "${name}". Names must start with alphanumeric and contain only letters, numbers, hyphens, and underscores. What it means
assertSafeSkillName validates skill names against SKILL_NAME_REGEX (/^[a-z0-9][a-z0-9-_]*$/i): must start with an alphanumeric and contain only letters, numbers, hyphens, and underscores. Anything else (spaces, dots, slashes, leading hyphen, unicode) triggers a 400.
Source
Thrown at packages/server/src/server/handlers/workspace.ts:1292
}
return handleError(error, 'Error fetching popular skills');
}
},
});
// =============================================================================
// Skills API helpers
// =============================================================================
/**
* Validate skill name to prevent path traversal attacks.
* Only allows alphanumeric characters, hyphens, and underscores.
*/
const SKILL_NAME_REGEX = /^[a-z0-9][a-z0-9-_]*$/i;
function assertSafeSkillName(name: string): string {
if (!SKILL_NAME_REGEX.test(name)) {
throw new HTTPException(400, {
message: `Invalid skill name "${name}". Names must start with alphanumeric and contain only letters, numbers, hyphens, and underscores.`,
});
}
return name;
}
/**
* Validate that a file path is safe (no traversal, no absolute paths).
* Prevents malicious API responses from writing files outside the skill directory.
*/
function assertSafeFilePath(filePath: string): string {
// Reject absolute paths
if (filePath.startsWith('/') || /^[a-zA-Z]:/.test(filePath)) {
throw new HTTPException(400, {
message: `Invalid file path "${filePath}". Absolute paths are not allowed.`,
});
}
// Reject path traversal attemptsView on GitHub (pinned to 75dd419e61)
Solutions
- Sanitize the name: lowercase, replace invalid characters with '-', strip leading non-alphanumerics.
- Trim file extensions before using a filename as a skill name.
- Validate on the client with the same regex before calling the API.
- If the name is inherently unsafe, use the ?path= disambiguation parameter instead of embedding it as a name.
Example fix
// before const name = 'My Skill.v2'; // after const name = 'My Skill.v2'.toLowerCase().replace(/[^a-z0-9-_]+/g, '-').replace(/^[^a-z0-9]+/, '');
Defensive patterns
Strategy: validation
Validate before calling
const SKILL_NAME_REGEX = /^[a-z0-9][a-z0-9-_]*$/i;
if (!SKILL_NAME_REGEX.test(name)) {
throw new Error(`Skill name "${name}" is invalid; use [a-z0-9][a-z0-9-_]*`);
} Type guard
function isValidSkillName(name: string): boolean {
return /^[a-z0-9][a-z0-9-_]*$/i.test(name);
} Try / catch
try {
return await client.getSkillByName(name);
} catch (e) {
if (isHttpException(e, 400) && String(e.message).includes('Invalid skill name')) {
return await client.getSkillByName(sanitizeSkillName(name));
}
throw e;
} Prevention
- Sanitize names derived from filenames (strip extensions, replace invalid chars with '-').
- Validate names with the same regex client-side before any API call.
- Never pass raw path fragments as skill names.
- Normalize user input (trim, lowercase) before sending.
When it happens
Trigger: Any route that calls assertSafeSkillName with a name like 'my skill', '.hidden', 'skill.v2', '/etc/passwd', or a name starting with '-' or '_'.
Common situations: Deriving the name from a filename (e.g. 'README.md'); user-supplied names with spaces or dots; path fragments accidentally passed as names; non-ASCII names from other locales.
Related errors
- Invalid skill name "${name}". Names must start with alphanum
- skillPath is missing SKILL.md: ${resolvedPath}
- Skill name and reference path are required
- Malformed referencePath
- bad request: ${responseText}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1159d67542b783ba.
Report an issue: GitHub.