mastra-ai/mastra · critical
Failed to clone repository: ${gitError instanceof Error ? gi
Error message
Failed to clone repository: ${gitError instanceof Error ? gitError.message : 'Unknown error'} What it means
When degit fails (including the empty-directory case), cloneTemplate falls back to `git clone <repoUrl> <tempTarget>`. If that git clone also throws, the error is rethrown wrapped as 'Failed to clone repository: <git message>' with the temp dir cleaned up. It is the terminal error meaning both scaffold strategies failed.
Source
Thrown at mastracode/mastra-factory/src/utils/clone.ts:73
if ((await fs.readdir(tempTarget)).length === 0) {
throw new Error('degit completed without cloning template files');
}
} catch {
await fs.rm(tempTarget, { recursive: true, force: true });
try {
await x('git', ['clone', repoUrl, tempTarget], {
throwOnError: true,
nodeOptions: { cwd: process.cwd() },
});
const gitDir = path.join(tempTarget, '.git');
if (await directoryExists(gitDir)) {
await fs.rm(gitDir, { recursive: true, force: true });
}
} catch (gitError) {
throw new Error(
`Failed to clone repository: ${gitError instanceof Error ? gitError.message : 'Unknown error'}`,
);
}
}
if (await pathExists(targetPath)) {
throw new Error(`Directory ${path.basename(targetPath)} already exists`);
}
await fs.rename(tempTarget, targetPath);
} finally {
await fs.rm(tempRoot, { recursive: true, force: true });
}
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Read the wrapped git message for the root cause (auth prompt, 404, DNS) and fix accordingly
- Verify the repo URL exists and is accessible: `git ls-remote <repoUrl>`
- For private repos, configure credentials (SSH key, token in the URL, or git credential helper)
- Ensure git is installed and on PATH (`git --version`)
- Check network/proxy settings if the remote is unreachable
Example fix
// before
await x('git', ['clone', 'https://github.com/acme/private-template.git', tempTarget], { throwOnError: true });
// after
await x('git', ['clone', 'https://<TOKEN>@github.com/acme/private-template.git', tempTarget], { throwOnError: true }); Defensive patterns
Strategy: try-catch
Validate before calling
const { code } = await x('git', ['ls-remote', repoUrl], { throwOnError: false });
if (code !== 0) throw new Error(`repo unreachable: ${repoUrl}`); Type guard
null
Try / catch
try {
await cloneTemplate(opts);
} catch (err) {
const msg = (err as Error).message;
if (msg.startsWith('Failed to clone repository')) {
console.error('Both degit and git clone failed:', msg);
// surface auth/network remediation to the user
} else throw err;
} Prevention
- Run `git ls-remote <url>` in CI before scaffolding
- Configure credentials (SSH keys or token URLs) for private templates
- Ensure git is installed in the runtime image
When it happens
Trigger: The degit path threw (caught by the outer catch), and the fallback `git clone repoUrl tempTarget` also failed — non-zero git exit, missing git binary, unreachable remote, bad URL, or cleanup of tempTarget itself throwing.
Common situations: Private repos without credentials, wrong repoUrl after a repo was renamed/deleted, no network or blocked git://(https) access, git not on PATH, or SSH keys absent when the URL is SSH-based.
Related errors
- Failed to clone repository: ${gitError instanceof Error ? gi
- Token exchange failed: ${error}
- Failed to fetch user info from Auth0
- Token exchange failed: ${error}
- Failed to fetch user info from Clerk
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/6b15813059647690.
Report an issue: GitHub.