nikivdev/code · error

Refusing to overwrite {}

Error message

Refusing to overwrite {}

What it means

copy_dir_all performs a strictly non-overwriting recursive copy: before copying each entry it checks whether the target path exists and aborts if so. This guards against races and against resuming onto a partially populated destination.

Source

Thrown at src/ext.rs:202

        if candidate.exists() {
            return current;
        }
        if !current.pop() {
            return cwd;
        }
    }
}

fn copy_dir_all(from: &Path, to: &Path) -> Result<()> {
    fs::create_dir_all(to).with_context(|| format!("failed to create {}", to.display()))?;
    for entry in fs::read_dir(from).with_context(|| format!("failed to read {}", from.display()))? {
        let entry = entry?;
        let path = entry.path();
        let file_type = entry.file_type()?;
        let target = to.join(entry.file_name());

        if target.exists() {
            bail!("Refusing to overwrite {}", target.display());
        }

        if file_type.is_dir() {
            copy_dir_all(&path, &target)?;
        } else if file_type.is_file() {
            fs::copy(&path, &target)
                .with_context(|| format!("failed to copy {}", path.display()))?;
        } else if file_type.is_symlink() {
            let link_target = fs::read_link(&path)
                .with_context(|| format!("failed to read link {}", path.display()))?;
            copy_symlink(&link_target, &target)?;
        }
    }
    Ok(())
}

fn copy_symlink(target: &Path, dest: &Path) -> Result<()> {
    #[cfg(unix)]

View on GitHub (pinned to a747e741ae)

Solutions

  1. Remove the partially populated destination directory entirely and re-run the import from scratch.
  2. Ensure no other process is writing to the destination concurrently.
  3. If re-importing intentionally, clear conflicting entries first rather than copying over them.

Example fix

// before
copy_dir_all(&source_workspace, &dest)?; // dest has leftovers
// after
if dest.exists() { std::fs::remove_dir_all(&dest)?; }
copy_dir_all(&source_workspace, &dest)?;
Defensive patterns

Strategy: validation

Validate before calling

fn dir_is_empty(p: &Path) -> std::io::Result<bool> {
    Ok(!p.exists() || std::fs::read_dir(p)?.next().is_none())
}
if !dir_is_empty(Path::new(&dest))? { /* clear or abort */ }

Type guard

fn copy_target_clear(to: &Path, name: &OsStr) -> bool {
    !to.join(name).exists()
}

Try / catch

match copy_dir_all(&src, &dest) {
    Err(e) if e.to_string().starts_with("Refusing to overwrite") => {
        std::fs::remove_dir_all(&dest)?; // clear partial copy
        copy_dir_all(&src, &dest)?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: Another process creates files in the destination between the top-level dest.exists() check and the copy loop; a previous failed import left partial files and copy_dir_all is re-invoked on the same target; recursive descent encounters a pre-existing subdirectory.

Common situations: Concurrent imports of the same source; cleaning up a failed import by deleting only some files; copying onto a directory that already contains a file with the same name (e.g. README.md).

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/1e57878c0b031bcb. Report an issue: GitHub.