mastra-ai/mastra · error · Error
Invalid GitHub URL format
Error message
Invalid GitHub URL format
What it means
`validateGitHubProject` in packages/cli/src/commands/create/create.ts:649 parses the given GitHub URL's pathname into owner/repo; if either segment is missing (e.g. a bare https://github.com or a single-segment path) it throws 'Invalid GitHub URL format', which is then surfaced as a validation failure ('Failed to validate GitHub repository: Invalid GitHub URL format'). The URL is only accepted when it contains exactly an owner and a repo (with optional .git suffix).
Source
Thrown at packages/cli/src/commands/create/create.ts:649
}
function looksLikeGitHubUrl(value: string): boolean {
try {
return new URL(value.startsWith('github.com/') ? `https://${value}` : value).hostname === 'github.com';
} catch {
return false;
}
}
async function validateGitHubProject(githubUrl: string): Promise<{ isValid: boolean; errors: string[] }> {
const errors: string[] = [];
try {
const urlParts = new URL(githubUrl).pathname.split('/').filter(Boolean);
const owner = urlParts[0];
const repo = urlParts[1]?.replace('.git', '');
if (!owner || !repo) throw new Error('Invalid GitHub URL format');
let packageJsonContent: string | null = null;
let indexContent: string | null = null;
for (const branch of ['main', 'master']) {
try {
const packageJsonResponse = await fetch(
`https://raw.githubusercontent.com/${owner}/${repo}/${branch}/package.json`,
);
if (!packageJsonResponse.ok) continue;
packageJsonContent = await packageJsonResponse.text();
const indexResponse = await fetch(
`https://raw.githubusercontent.com/${owner}/${repo}/${branch}/src/mastra/index.ts`,
);
if (indexResponse.ok) indexContent = await indexResponse.text();
break;
} catch {View on GitHub (pinned to 75dd419e61)
Solutions
- Provide a full repository URL: `--template https://github.com/<owner>/<repo>`
- Append `.git` optionally — it is stripped automatically
- Strip query strings/fragments (`?tab=readme`, `#readme`) before passing
- If using a template slug instead, pass just the slug, not a partial URL
Example fix
// before mastra create my-app --template https://github.com/mastra-ai // after mastra create my-app --template https://github.com/mastra-ai/template-agent-harness
Defensive patterns
Strategy: validation
Validate before calling
export function normalizeGitHubTemplateUrl(input: string): string {
const url = new URL(input.startsWith('github.com/') ? `https://${input}` : input);
if (url.hostname !== 'github.com' || url.protocol !== 'https:') {
throw new Error(`Not a GitHub repository URL: ${input}`);
}
const parts = url.pathname.split('/').filter(Boolean);
if (parts.length < 2) throw new Error(`GitHub URL must include owner and repo: ${input}`);
return `https://github.com/${parts[0]}/${parts[1].replace(/\.git$/, '')}`;
} Type guard
function isRepoUrl(value: string): boolean {
try {
const u = new URL(value);
const parts = u.pathname.split('/').filter(Boolean);
return u.hostname === 'github.com' && parts.length >= 2;
} catch { return false; }
} Try / catch
try {
await create({ template: githubUrl });
} catch (error) {
if (error instanceof Error && /Invalid GitHub URL|Invalid Mastra project/.test(error.message)) {
console.error('Provide a full owner/repo GitHub URL');
} else throw error;
} Prevention
- Always pass full owner/repo URLs, not org or profile pages
- Strip ?query and #fragment before passing template URLs
- Validate with new URL() and count pathname segments (must be 2) before invoking
When it happens
Trigger: Passing `--template https://github.com/mastra` (owner only), `--template https://github.com/`, or a malformed URL that survived parseGitHubRepositoryUrl's normalization but has <2 path segments.
Common situations: Copying a user/org profile URL instead of a repository URL; truncated URLs pasted into shells; URL-encoded paths or fragments altering segment counts; typos dropping the repo part.
Related errors
- Invalid GitHub repository URL. Use https://github.com/<owner
- Invalid GitHub URL: ${specifier}
- Only github.com plugin URLs are supported
- GitHub plugin URL must be in the form https://github.com/own
- No template selected
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/7409385939939146.
Report an issue: GitHub.