rust-lang/cargo · error · anyhow::Error

{err}

Error message

{err}

What it means

Catch-all IO error while reading lines of an existing ignore file in IgnoreList::format_existing. The InvalidData (non-UTF-8) case is handled separately (error 114); any other io::Error kind (permission denied, disk I/O, broken pipe, etc.) is wrapped and re-thrown here. The {err} is the original std::io::Error Display.

Source

Thrown at src/ops/cargo_new.rs:665

    }

    /// `format_existing` is used to format the `IgnoreList` when the ignore file
    /// already exists. It reads the contents of the given `BufRead` and
    /// checks if the contents of the ignore list are already existing in the
    /// file.
    fn format_existing<T: BufRead>(&self, existing: T, vcs: VersionControl) -> CargoResult<String> {
        let mut existing_items = Vec::new();
        for (i, item) in existing.lines().enumerate() {
            match item {
                Ok(s) => existing_items.push(s),
                Err(err) => match err.kind() {
                    ErrorKind::InvalidData => {
                        return Err(anyhow!(
                            "Character at line {} is invalid. Cargo only supports UTF-8.",
                            i
                        ));
                    }
                    _ => return Err(anyhow!(err)),
                },
            }
        }

        let ignore_items = match vcs {
            VersionControl::Hg => &self.hg_ignore,
            VersionControl::Fossil => &self.fossil_ignore,
            _ => &self.ignore,
        };

        let mut out = String::new();

        // Fossil does not support `#` comments.
        if vcs != VersionControl::Fossil {
            out.push_str("\n\n# Added by cargo\n");
            if ignore_items
                .iter()
                .any(|item| existing_items.contains(item))

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Check permissions: `ls -l .gitignore` and `chmod`/`chown` as needed
  2. Fix or remove dangling symlinks: `ls -la` and `rm` the broken link
  3. Verify the path is a regular file and not a directory
  4. Retry after resolving the underlying filesystem/IO issue

Example fix

# before: .gitignore unreadable (mode 000)
cargo init   # -> io error
# after
chmod 644 .gitignore
cargo init
Defensive patterns

Strategy: try-catch

Validate before calling

use std::path::Path;
fn ensure_ignore_readable(path: &Path) -> std::io::Result<()> {
    let meta = std::fs::metadata(path)?;
    if !meta.is_file() { return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "not a regular file")); }
    std::fs::File::open(path)?.read_to_end(&mut Vec::new())?;
    Ok(())
}

ensure_ignore_readable(Path::new(".gitignore"))?;

Type guard

import { statSync, accessSync, constants } from 'fs';
function isReadableFile(path: string): boolean {
  try { const s = statSync(path); return s.isFile() && accessSync(path, constants.R_OK) === undefined; }
  catch { return false; }
}

Try / catch

match std::fs::read_to_string(ignore_path) {
    Ok(content) => { /* proceed */ }
    Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
        eprintln!("fix permissions on {} then retry", ignore_path.display());
        return Err(e.into());
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: `cargo new`/`cargo init` where the existing `.gitignore`/`.hgignore`/`.ignore` exists but cannot be read due to permission errors, the file being a dangling symlink, a read error mid-file, or the path being a directory.

Common situations: File mode 000 owned by another user; broken symlink in a partially-restored backup; NFS/SMB hiccup mid-read; .gitignore is accidentally a directory; read-only filesystem mounts.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/1ec86465bafa6509.json. Report an issue: GitHub.