{"record":{"id":"bbcdab24392f5ca7","repo":"vercel-labs/skills","slug":"failed-to-clone-url-errormessage","errorCode":null,"errorMessage":"Failed to clone ${url}: ${errorMessage}","messagePattern":"Failed to clone (.+?): (.+?)","errorType":"exception","errorClass":"GitCloneError","httpStatus":null,"severity":"error","filePath":"src/git.ts","lineNumber":297,"sourceCode":"        await resetTempDir(tempDir);\n        await createGitClient(process.env.GIT_SSH_COMMAND ?? 'ssh -o BatchMode=yes').clone(\n          repo.sshUrl,\n          tempDir,\n          cloneOptions\n        );\n        return tempDir;\n      } catch {\n        // Fall through to the targeted auth error below.\n      }\n    }\n\n    await rm(tempDir, { recursive: true, force: true }).catch(() => {});\n\n    if (isAuthError) {\n      throw new GitCloneError(buildGitHubAuthError(url, repo, errorMessage), url, false, true);\n    }\n\n    throw new GitCloneError(`Failed to clone ${url}: ${errorMessage}`, url, false, false);\n  }\n}\n\n/**\n * Resolve the Git tree object for a locked skill path in a cloned repository.\n * This matches the folder SHA returned by GitHub's Trees API.\n */\nexport async function getGitTreeHash(repoDir: string, skillPath: string): Promise<string | null> {\n  const normalizedPath = skillPath.replace(/\\\\/g, '/');\n  const segments = normalizedPath.split('/');\n  segments.pop();\n  const folderPath = segments.join('/');\n  const revision = folderPath ? `HEAD:${folderPath}` : 'HEAD^{tree}';\n\n  try {\n    const stdout = await new Promise<string>((resolve, reject) => {\n      execFile(\n        'git',","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/vercel-labs/skills/blob/435076e78988e1e6ec40d00b0b1d76bdbbc5419a/src/git.ts#L279-L315","documentation":"The generic clone failure in cloneRepo(): git exited non-zero, it was neither a timeout nor an auth error, so the raw git stderr is wrapped: 'Failed to clone <url>: <message>'. The temp directory is cleaned up before throwing.","triggerScenarios":"Any non-timeout, non-auth git failure: repository not found (HTTPS 404 on public repo), invalid ref/branch name, malformed URL, DNS failure ('Could not resolve host'), disk full, or unsupported git protocol.","commonSituations":"Typos in owner/repo shorthand; deleted or renamed repositories; branch specified doesn't exist; corporate proxies blocking git:// protocol; old git versions lacking needed features.","solutions":["Copy the git stderr from the message and reproduce manually: git clone --depth 1 <url> to see the full failure","Fix the URL/branch: verify the repo exists in a browser and the branch name is correct","If DNS/proxy: configure https.proxy or correct corporate proxy env vars","If repo is private, see auth errors — sometimes 404 masks missing credentials"],"exampleFix":"# before (branch typo)\nskills add github.com/org/repo --ref maain\n# after\nskills add github.com/org/repo --ref main","handlingStrategy":"try-catch","validationCode":"const exists = await fetch(`https://api.github.com/repos/${owner}/${repo}`, {\n  headers: token ? { Authorization: `Bearer ${token}` } : {},\n}).then((r) => r.ok);\nif (!exists) throw new Error(`Repo ${owner}/${repo} not reachable; check spelling/visibility`);","typeGuard":"function isGitCloneError(e: unknown): e is Error {\n  return e instanceof Error && /^Failed to clone /.test(e.message);\n}","tryCatchPattern":"try { await cloneRepo(url, ref); }\ncatch (e) {\n  if (isGitCloneError(e)) {\n    logger.error(e.message); // contains raw git stderr for diagnosis\n    return fallbackToLocalMirror(url);\n  }\n  throw e;\n}","preventionTips":["Validate owner/repo spelling and branch names before cloning","Reproduce failures manually with git clone --depth 1","Wrap cloneRepo and surface the embedded git stderr to users"],"tags":["git","clone","repository-not-found"],"backgroundTag":"git-clone-failed","analyzedSha":"435076e78988e1e6ec40d00b0b1d76bdbbc5419a","analyzedAt":"2026-08-28T17:47:53.369Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}