mastra-ai/mastra · error · Error
GitHub owner and repo may only contain letters, numbers…
Error message
GitHub owner and repo may only contain letters, numbers, dots, underscores, and dashes
What it means
After structural validation, parseGithubUrl checks the owner and repo (with a trailing '.git' stripped) against /^[A-Za-z0-9_.-]+$/. Characters outside that set — e.g. URL-encoded, Unicode, or shell metacharacters — are rejected to prevent path/shell injection when the SDK clones the repo and writes into the plugin directory.
Solutions
- Use the exact owner/repo names as they appear on github.com (letters, numbers, dots, underscores, dashes only).
- Remove URL encoding — write the literal ASCII name, not percent-encoded forms.
- Drop non-standard suffixes like '~branch' from the repo segment; use the '#ref' fragment for refs instead.
Example fix
// before
await installPlugin('https://github.com/acme/widgets%20pro');
// after
await installPlugin('https://github.com/acme/widgets-pro'); Defensive patterns
Strategy: validation
Validate before calling
const NAME_RE = /^[A-Za-z0-9_.-]+$/;
function hasValidOwnerRepo(specifier: string): boolean {
try {
const [owner, repo = ''] = new URL(specifier.split('#')[0]).pathname.split('/').filter(Boolean);
return NAME_RE.test(owner) && NAME_RE.test(repo.replace(/\.git$/, ''));
} catch {
return false;
}
} Try / catch
try {
await installPlugin(specifier);
} catch (error) {
if (error instanceof Error && error.message.startsWith('GitHub owner and repo may only contain')) {
throw new Error(`Owner/repo in "${specifier}" contain unsupported characters; use the literal GitHub name`);
}
throw error;
} Prevention
- Never percent-encode owner/repo names in plugin specifiers.
- Test owner/repo against /^[A-Za-z0-9_.-]+$/ in your own URL builder.
- Move refs/suffixes into the '#ref' fragment instead of the repo segment.
When it happens
Trigger: Specifiers with percent-encoded or special characters in owner/repo, like 'https://github.com/own%65r/repo' resolving to odd names, 'https://github.com/owner/repo~branch', or names containing '+', '@', or spaces.
Common situations: Hand-editing the URL and introducing characters that are not valid in GitHub owner/repo names; pasting a URL from a system that URL-encoded the path; repo names with unusual suffixes.
Related errors
- A multi-line review comment requires both startLine and…
- A review comment requires commitId, path, line, and side…
- A review comment requires commitId, path, line, and side…
- clone-failed
- Factory rules.github must be an object.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b17838436a76eb3f.
Report an issue: GitHub.
Appendix: source
Thrown at mastracode/sdk/src/plugins/install.ts:248
let url: URL;
try {
url = new URL(urlPart);
} catch {
throw new Error(`Invalid GitHub URL: ${specifier}`);
}
if (url.hostname !== 'github.com') {
throw new Error('Only github.com plugin URLs are supported');
}
const [owner, rawRepo, ...rest] = url.pathname.split('/').filter(Boolean);
if (!owner || !rawRepo || rest.length > 0) {
throw new Error('GitHub plugin URL must be in the form https://github.com/owner/repo');
}
const repo = rawRepo.replace(/\.git$/, '');
if (!/^[A-Za-z0-9_.-]+$/.test(owner) || !/^[A-Za-z0-9_.-]+$/.test(repo)) {
throw new Error('GitHub owner and repo may only contain letters, numbers, dots, underscores, and dashes');
}
return {
owner,
repo,
repoSpec: `${owner}/${repo}`,
...(ref ? { ref } : {}),
};
}
View on GitHub (pinned to 75dd419e61)