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
- Raise the limit: SKILLS_CLONE_TIMEOUT_MS=600000 skills add <repo>
- Check credentials so git doesn't stall: ssh-add -l for SSH, gh auth status for HTTPS
- Retry on a better network, or clone manually and pass the local path: git clone <url> /tmp/r && skills add /tmp/r
- 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
- Pre-flight with git ls-remote to gauge reachability
- Set SKILLS_CLONE_TIMEOUT_MS higher for known-large repos
- Ensure credentials are configured so git never blocks on prompts
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Failed to clone ${url}: ${errorMessage}
- Download failed with HTTP ${response.status}
- Download response has no body
- Downloaded URL is empty
- Unsupported Git transport: ext
AI-assisted analysis of vercel-labs/skills@435076e789 (2026-08-28).
Data as JSON: /api/errors/3b0e3d62a765c20e.
Report an issue: GitHub.