nikivdev/code · error

Refusing to overwrite {}

Error message

Refusing to overwrite {}

What it means

Thrown by copy_dir_all in archive.rs when, during the recursive archive copy, a destination path already exists. The tool refuses to clobber existing files/directories rather than silently overwrite user data.

Source

Thrown at src/archive.rs:122

            .and_then(|name| name.to_str())
            .map(|name| self.skip_names.contains(&name))
            .unwrap_or(false)
    }
}

fn copy_dir_all(from: &Path, to: &Path, filter: &ArchiveFilter) -> 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();
        if filter.should_skip(&path) {
            continue;
        }
        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, filter)?;
        } 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 or rename the existing archive directory at the target path before re-running
  2. Use a different archive message to get a unique slug
  3. Add logic in the caller to pick a unique destination (timestamped suffix) before copying

Example fix

// before
archive --message "snapshot"   # snapshot already archived
// after
archive --message "snapshot-2026-09-01"   # unique slug avoids collision
Defensive patterns

Strategy: validation

Validate before calling

fn archive_target_free(home: &Path, slug: &str) -> bool {
    !home.join("archive").join("code").join(slug).exists()
}
if !archive_target_free(&home, &slug) {
    eprintln!("archive target already exists; pick a new message");
}

Try / catch

match archive::run(opts) {
    Err(e) if e.to_string().starts_with("Refusing to overwrite") => {
        eprintln!("{}\nRemove/rename the existing archive or change the message.", e);
        std::process::exit(2);
    }
    other => other,
}

Prevention

When it happens

Trigger: copy_dir_all (recursively, and via run or copy_symlink) encounters target.join(file_name) that already exists in the destination archive directory — e.g. archiving into a directory from a previous run with the same slug.

Common situations: Re-running the archive with the same message slug after a partial or completed previous archive; leftover files from an interrupted run; archives that share names across projects in ~/archive/code.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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