vercel-labs/skills · error · GitCloneError

Clone timed out after ${seconds}s. Common causes: - Large

Error message

Clone timed out after ${seconds}s. Common causes:
  - Large repository: raise the timeout with SKILLS_CLONE_TIMEOUT_MS=600000 (10m)
  - Slow network: retry, or clone manually and pass the local path to 'skills add'
  - Private repo without credentials: ensure auth is configured
      - For SSH: ssh-add -l (to check loaded keys)
      - For HTTPS: gh auth status (if using GitHub CLI)

What it means

cloneRepo() enforces a global clone timeout (CLONE_TIMEOUT_MS, configurable via SKILLS_CLONE_TIMEOUT_MS). When the underlying git process fails with a timeout/blocked-timeout message, the temp clone dir is removed and this GitCloneError with remediation hints is thrown.

Source

Thrown at src/git.ts:255

    throw new GitCloneError('Unsupported Git transport: ext', url);
  }

  const tempDir = await mkdtemp(join(tmpdir(), 'skills-'));
  const cloneOptions = ref ? ['--depth', '1', '--branch', ref] : ['--depth', '1'];
  const repo = parseGitHubRepoUrl(url);

  try {
    await createGitClient().clone(url, tempDir, cloneOptions);
    return tempDir;
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    const isTimeout = errorMessage.includes('block timeout') || errorMessage.includes('timed out');
    const isAuthError = isAuthFailure(errorMessage);

    if (isTimeout) {
      await rm(tempDir, { recursive: true, force: true }).catch(() => {});
      const seconds = Math.round(CLONE_TIMEOUT_MS / 1000);
      throw new GitCloneError(
        `Clone timed out after ${seconds}s. Common causes:\n` +
          `  - Large repository: raise the timeout with SKILLS_CLONE_TIMEOUT_MS=600000 (10m)\n` +
          `  - Slow network: retry, or clone manually and pass the local path to 'skills add'\n` +
          `  - Private repo without credentials: ensure auth is configured\n` +
          `      - For SSH: ssh-add -l (to check loaded keys)\n` +
          `      - For HTTPS: gh auth status (if using GitHub CLI)`,
        url,
        true,
        false
      );
    }

    if (isAuthError && repo && isGitHubHttpsCloneUrl(url)) {
      try {
        await resetTempDir(tempDir);
        if (await tryGhClone(repo, tempDir, ref)) {
          return tempDir;
        }

View on GitHub (pinned to 435076e789)

Solutions

  1. Raise the limit: SKILLS_CLONE_TIMEOUT_MS=600000 skills add <repo>
  2. Check credentials so git doesn't stall: ssh-add -l for SSH, gh auth status for HTTPS
  3. Retry on a better network, or clone manually and pass the local path: git clone <url> /tmp/r && skills add /tmp/r
  4. If it's a huge monorepo, clone with sparse checkout yourself and add the local path

Example fix

# before
skills add github.com/org/huge-monorepo   # times out
# after
SKILLS_CLONE_TIMEOUT_MS=600000 skills add github.com/org/huge-monorepo
Defensive patterns

Strategy: retry

Validate before calling

import { execSync } from 'node:child_process';
function repoLikelyCloneable(url: string): boolean {
  try { execSync(`git ls-remote --heads ${JSON.stringify(url)}`, { timeout: 15000, stdio: 'ignore' }); return true; }
  catch { return false; }
}

Type guard

function isCloneTimeout(e: unknown): e is Error {
  return e instanceof Error && /Clone timed out/i.test(e.message);
}

Try / catch

try { await cloneRepo(url); }
catch (e) {
  if (isCloneTimeout(e)) {
    process.env.SKILLS_CLONE_TIMEOUT_MS = '600000';
    return await cloneRepo(url); // one retry with raised timeout
  }
  throw e;
}

Prevention

When it happens

Trigger: A 'git clone --depth 1' exceeding CLONE_TIMEOUT_MS — typically monorepos with large history or LFS objects, very slow networks, or a private repo silently hanging on credential prompts.

Common situations: Adding big skill monorepos over slow links; CI runners with constrained egress; SSH keys not loaded so git blocks on passphrase/auth until timeout.

Understand the failure class

Related errors


AI-assisted analysis of vercel-labs/skills@435076e789 (2026-08-28). Data as JSON: /api/errors/3b0e3d62a765c20e. Report an issue: GitHub.