Skip to content
Latchkey

git "destination path already exists" on a self-hosted runner in CI

A git clone (or a manual clone step) targets a directory that already contains files from a previous run, so git refuses to write into it. Self-hosted runners keep the workspace between jobs, so leftover files collide with a fresh clone.

What this error means

A clone fails with "fatal: destination path 'app' already exists and is not an empty directory." on a self-hosted runner, while the same step works on a fresh hosted runner.

git
fatal: destination path 'app' already exists and is not an empty directory.

Common causes

The self-hosted workspace was not cleaned

Persistent self-hosted runners keep files from prior jobs. A raw git clone into that path finds a non-empty directory and aborts.

A manual clone instead of actions/checkout

actions/checkout cleans and reuses the workspace safely; a hand-written git clone does not, so it collides with leftovers.

How to fix it

Let actions/checkout clean the workspace

Use actions/checkout with clean enabled (the default) so the workspace is reset each run.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    clean: true

Clean before a manual clone

  1. Remove or empty the target directory before cloning.
  2. Or clone into a fresh path and remove the old one first.
  3. Prefer actions/checkout over hand-written clones on self-hosted runners.
Terminal
rm -rf app && git clone https://github.com/acme/app.git app

How to prevent it

  • Use actions/checkout (with clean) rather than manual clones on self-hosted runners.
  • Reset the workspace at the start of jobs that reuse a runner.
  • Do not clone into a directory that a previous job populated.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →