{"record":{"id":"ec5407888a1b3d0a","repo":"abhigyanpatwari/GitNexus","slug":"clone-target-already-exists-but-is-not-a-git-repos","errorCode":null,"errorMessage":"Clone target already exists but is not a git repository: ${safeTarget}","messagePattern":"Clone target already exists but is not a git repository: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/server/git-clone.ts","lineNumber":450,"sourceCode":"        // ignored paths must survive, and `-e /.gitnexus` is belt-and-braces\n        // because `.git/info/exclude` is skipped on a read-only storage mount\n        // and a freshly cloned repo may not have been analyzed yet at all.\n        await runGitImpl(['clean', '--force', '-d', '-e', '/.gitnexus'], safeTarget, {\n          token: options?.token,\n          url,\n          timeoutMs: options?.timeoutMs,\n        });\n      }\n    } else {\n      await runGitImpl(['pull', '--ff-only'], safeTarget, {\n        token: options?.token,\n        url,\n        timeoutMs: options?.timeoutMs,\n      });\n    }\n  } else {\n    if (targetExists && (await fs.readdir(safeTarget)).length > 0) {\n      throw new Error(`Clone target already exists but is not a git repository: ${safeTarget}`);\n    }\n    onProgress?.({ phase: 'cloning', message: `Cloning ${url}...` });\n    try {\n      const runGitImpl = options?.runGitForTest ?? runGit;\n      const cloneArgs = options?.branch\n        ? buildBranchCloneArgs(url, safeTarget, options.branch)\n        : buildCloneArgs(url, safeTarget);\n      await runGitImpl(cloneArgs, undefined, {\n        token: options?.token,\n        url,\n        timeoutMs: options?.timeoutMs,\n      });\n      await assertPostRealpathContainment(cloneRoot, safeTarget);\n    } catch (err: unknown) {\n      if (options?.quarantineRoot) {\n        const partialExists = await fs.access(safeTarget).then(\n          () => true,\n          () => false,","sourceCodeStart":432,"sourceCodeEnd":468,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/server/git-clone.ts#L432-L468","documentation":"When the target is not (yet) recognized as a git repository and targetDir already exists non-empty, cloneOrPull refuses to clone over it. Cloning into a non-empty, non-git directory would either fail or mix foreign files into the checkout, so the library fails fast instead.","triggerScenarios":"targetDir exists and contains files but has no .git directory (deleted .git, half-deleted clone, or a directory that was never a repo); a previous failed run left partial files after quarantine was skipped; the user pointed targetDir at an unrelated folder.","commonSituations":"Manual 'rm -rf .git' or antivirus deleting .git; a previous clone failing mid-write; reusing an existing project folder as the clone destination; path collisions from a previous differently-named clone layout.","solutions":["Delete or empty the target directory, then retry the clone.","Re-initialize it as a proper git repo (git init + set remote) if the content should be preserved, or clone elsewhere and migrate.","Point targetDir at a fresh path inside the clone root.","Investigate what left the non-git files there before removing them."],"exampleFix":"// before\nawait cloneOrPull({ url, targetDir: '/clones/repo' }); // dir has stale files, no .git\n// after\nawait fs.rm('/clones/repo', { recursive: true, force: true });\nawait cloneOrPull({ url, targetDir: '/clones/repo' });","handlingStrategy":"validation","validationCode":"import { fs } from '...'; // node:fs/promises\nlet isRepo = false, empty = true;\ntry {\n  await fs.access(path.join(targetDir, '.git'));\n  isRepo = true;\n} catch {}\ntry {\n  empty = (await fs.readdir(targetDir)).length === 0;\n} catch {}\nif (!isRepo && !empty) throw new Error(`Clean or remove non-git directory ${targetDir} before cloning`);","typeGuard":null,"tryCatchPattern":"try {\n  await cloneOrPull(opts);\n} catch (err) {\n  if ((err as Error).message.startsWith('Clone target already exists but is not a git repository')) {\n    await fs.rm(opts.targetDir, { recursive: true, force: true });\n    return cloneOrPull(opts);\n  }\n  throw err;\n}","preventionTips":["Clone only into fresh, managed directories inside the clone root.","Never point clone targets at pre-existing project folders.","After a failed clone, let the quarantine logic clean up instead of manually deleting only .git.","Monitor for processes (e.g. antivirus) that delete .git directories."],"tags":["git","clone","filesystem"],"backgroundTag":"file-already-exists","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-09-08T00:40:44.970Z","contentChangedAt":"2026-09-08T00:40:44.970Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}