vectordotdev/vector · error

Failed to read dir

Error message

Failed to read dir: {input_path:?}

What it means

walk_dir_and_convert recursively converts all supported config files under a directory. It calls fs::read_dir on the input directory and, if listing fails, panics with 'Failed to read dir: <path>' rather than recording the error in its collected error list.

Solutions

  1. Check directory readability: `ls <dir>` / verify with `test -r <dir>`
  2. Run the tool with sufficient permissions or as the directory owner
  3. Fix or remove broken symlinks pointing at nonexistent targets
  4. Patch to push the io::Error into the errors Vec instead of panicking

Example fix

// before
fs::read_dir(input_path)
    .unwrap_or_else(|_| panic!("Failed to read dir: {input_path:?}"))
// after
let entries = match fs::read_dir(input_path) {
    Ok(e) => e,
    Err(err) => {
        errors.push(format!("Failed to read dir {input_path:?}: {err}"));
        return Ok(());
    }
};
Defensive patterns

Strategy: validation

Validate before calling

if !fs::metadata(dir).map(|m| m.is_dir()).unwrap_or(false) || fs::read_dir(dir).is_err() {
    eprintln!("directory {:?} is not readable", dir);
    std::process::exit(2);
}

Type guard

fn is_readable_dir(p: &std::path::Path) -> bool { fs::read_dir(p).is_ok() }

Prevention

When it happens

Trigger: Calling walk_dir_and_convert (directly or via cmd/convert_all_from_dir) on a path that was a directory at the is_dir() check but cannot be listed: permission denied, directory deleted concurrently, or it is a symlink to an unreadable location.

Common situations: Running the recursive converter on directories with restrictive permissions (e.g. another user's home), racing with cleanup jobs that delete directories, or broken symlinks to directories.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/7e704553ba495c42. Report an issue: GitHub.

Appendix: source

Thrown at src/convert_config.rs:155

    fs::write(output_path, output_string).map_err(|e| vec![e.to_string()])?;

    #[allow(clippy::print_stdout)]
    {
        println!("Wrote result to {output_path:?}.");
    }
    Ok(())
}

fn walk_dir_and_convert(
    input_path: &Path,
    output_dir: &Path,
    output_format: Format,
) -> Result<(), Vec<String>> {
    let mut errors = Vec::new();

    if input_path.is_dir() {
        for entry in fs::read_dir(input_path)
            .unwrap_or_else(|_| panic!("Failed to read dir: {input_path:?}"))
        {
            let entry_path = entry
                .unwrap_or_else(|_| panic!("Failed to get entry for dir: {input_path:?}"))
                .path();
            let new_output_dir = if entry_path.is_dir() {
                let last_component = entry_path
                    .file_name()
                    .unwrap_or_else(|| panic!("Failed to get file_name for {entry_path:?}"));
                let new_dir = output_dir.join(last_component);

                if !new_dir.exists() {
                    fs::create_dir_all(&new_dir)
                        .unwrap_or_else(|_| panic!("Failed to create output dir: {new_dir:?}"));
                }
                new_dir
            } else {
                output_dir.to_path_buf()
            };

View on GitHub (pinned to bdb87aeaa4)