astral-sh/ruff · error · io::Error

File already exists

Error message

File already exists

What it means

This io::Error (kind AlreadyExists) is raised by the in-memory file system's `create_new_file` when a file already exists at the target path. It mirrors the semantics of `std::fs::OpenOptions::create_new(true)`, which must never overwrite an existing file.

Source

Thrown at crates/ruff_db/src/system/memory_fs.rs:182

    pub(crate) fn create_new_file(&self, path: &SystemPath) -> Result<()> {
        let normalized = self.normalize_path(path);

        let mut by_path = self.inner.by_path.write().unwrap();
        match by_path.entry(normalized) {
            btree_map::Entry::Vacant(entry) => {
                let parent = entry.key().parent().map(Utf8Path::to_path_buf);
                entry.insert(Entry::File(File {
                    content: Box::default(),
                    last_modified: file_time_now(),
                }));
                if let Some(parent) = parent {
                    touch_directory(&mut by_path, &parent);
                }

                Ok(())
            }
            btree_map::Entry::Occupied(_) => Err(io::Error::new(
                io::ErrorKind::AlreadyExists,
                "File already exists",
            )),
        }
    }

    /// Stores a new file in the file system.
    ///
    /// The operation overrides the content for an existing file with the same normalized `path`.
    pub fn write_file(
        &self,
        path: impl AsRef<SystemPath>,
        content: impl AsRef<[u8]>,
    ) -> Result<()> {
        let mut by_path = self.inner.by_path.write().unwrap();

        let normalized = self.normalize_path(path.as_ref());
        let file = get_or_create_file(&mut by_path, &normalized)?;

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Check existence first with a read/lookup, or remove the existing file before creating
  2. Use a write/overwrite API if replacement is intended instead of exclusive creation
  3. Generate unique paths (e.g. temp-style unique names) for each new file

Example fix

// before
fs.create_new_file(path, contents)?; // fails if path exists
// after
if fs.read_file(path).is_ok() {
    fs.remove_file(path)?;
}
fs.create_new_file(path, contents)?;
Defensive patterns

Strategy: validation

Validate before calling

if fs.read_file(path).is_ok() {
    return Err(io::Error::new(io::ErrorKind::AlreadyExists, "path exists"));
}

Type guard

fn path_is_free(fs: &MemoryFileSystem, path: &VfsPath) -> bool {
    fs.read_file(path).is_err()
}

Try / catch

match fs.create_new_file(path, contents) {
    Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => reuse_or_replace(path, contents),
    Err(e) => return Err(e),
    Ok(()) => (),
}

Prevention

When it happens

Trigger: Calling `create_new_file` (or APIs built on it, like exclusive file creation in tests) with a path that already has an entry in the memory FS's `by_path` map.

Common situations: Test setups that create fixture files without checking existence, repeated setup of the same memory FS path across subtests, race-like double initialization in tooling using the memory FS.

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 astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/131769ea631049b9. Report an issue: GitHub.