mastra-ai/mastra · error · Error

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 the degit path fails, cloneRepositoryWithoutGit falls back to `git clone`; if that git invocation throws, the original error is discarded and rewrapped as 'Failed to clone repository: <git message>'. The catch also rethrows abort errors unchanged and cleans up the target dir before the fallback path.

Source

Thrown at packages/cli/src/utils/clone-template.ts:135

      if (branch) {
        gitArgs.push('--branch', branch);
      }
      gitArgs.push(repoUrl, targetPath);

      await execa('git', gitArgs, {
        cwd: process.cwd(),
        ...(signal ? { cancelSignal: signal } : {}),
      });
      signal?.throwIfAborted();

      // Remove .git directory
      const gitDir = path.join(targetPath, '.git');
      if (await directoryExists(gitDir)) {
        await fs.rm(gitDir, { recursive: true, force: true });
      }
    } catch (gitError) {
      if (signal?.aborted) signal.throwIfAborted();
      throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : 'Unknown error'}`);
    }
  }
}

async function updatePackageJson(projectPath: string, projectName: string): Promise<void> {
  const packageJsonPath = path.join(projectPath, 'package.json');

  try {
    const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');
    const packageJson = JSON.parse(packageJsonContent);

    // Update the name field
    packageJson.name = projectName;

    // Write back the updated package.json
    await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');
  } catch (error) {
    // It's okay if package.json doesn't exist or can't be updated

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Read the wrapped git message (e.g. 'could not resolve host', 'Authentication failed') and fix the underlying cause — network, proxy, or credentials.
  2. Verify git is installed and on PATH (git --version).
  3. Confirm the template repository URL and branch exist and are publicly accessible (or configure a GitHub token/SSH key).
  4. Retry after restoring connectivity; the target directory is cleaned before fallback, so a fresh run is safe.

Example fix

// before (private repo, no auth)
// Error: Failed to clone repository: Authentication failed for 'https://github.com/org/private-template.git/'

// after
$ git config --global credential.helper store
$ gh auth login   # or use an SSH remote / PAT
Defensive patterns

Strategy: try-catch

Validate before calling

import { execFile } from 'node:child_process';
execFile('git', ['--version'], (err) => { if (err) throw new Error('git is not installed or not on PATH'); });

Type guard

function isGitError(e: unknown): e is Error & { killed?: boolean } {
  return e instanceof Error;
}

Try / catch

try {
  await cloneTemplate(opts);
} catch (err) {
  const msg = err instanceof Error ? err.message : String(err);
  if (msg.startsWith('Failed to clone repository:')) {
    console.error('git clone failed:', msg); // inspect underlying git reason
  }
  throw err;
}

Prevention

When it happens

Trigger: cloneTemplate -> cloneRepositoryWithoutGit fallback `git clone <githubUrl> <targetPath>` exits non-zero (any gitError), and signal is not aborted.

Common situations: No git installed or git not on PATH; no network access / corporate proxy blocking github.com; repo private (auth required) or removed; invalid branch name; SSH/HTTPS auth failures; SSL certificate issues.

Related errors


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