BurntSushi/ripgrep · error

<stdin> has no metadata

Error message

<stdin> has no metadata

What it means

DirEntry::metadata() delegates to DirEntryInner::metadata(); for the Stdin variant it unconditionally returns Err with '<stdin> has no metadata'. Stdin is a synthetic directory entry with no underlying file, so file size/times/permissions are undefined and the API refuses to fabricate them.

Source

Thrown at crates/ignore/src/walk.rs:176

        match *self {
            Stdin => false,
            Walkdir(ref x) => x.path_is_symlink(),
            Raw(ref x) => x.path_is_symlink(),
        }
    }

    fn is_stdin(&self) -> bool {
        match *self {
            DirEntryInner::Stdin => true,
            _ => false,
        }
    }

    fn metadata(&self) -> Result<Metadata, Error> {
        use self::DirEntryInner::*;
        match *self {
            Stdin => {
                let err = Error::Io(io::Error::new(
                    io::ErrorKind::Other,
                    "<stdin> has no metadata",
                ));
                Err(err.with_path("<stdin>"))
            }
            Walkdir(ref x) => x.metadata().map_err(|err| {
                Error::Io(io::Error::from(err))
                    .with_depth(x.depth())
                    .with_path(x.path())
            }),
            Raw(ref x) => x.metadata(),
        }
    }

    fn file_type(&self) -> Option<FileType> {
        use self::DirEntryInner::*;
        match *self {
            Stdin => None,

View on GitHub (pinned to 3fce3b5bb0)

Solutions

  1. Guard the call: if entry.is_stdin() { /* skip metadata-dependent logic */ } before calling metadata().
  2. Treat the error as expected for stdin entries and fall back to streaming search without size-based heuristics.
  3. When you need size/mtime, require a real file path instead of stdin.

Example fix

// before
let md = entry.metadata()?; // errors for stdin

// after
let md = if entry.is_stdin() {
    None
} else {
    Some(entry.metadata()?)
};
Defensive patterns

Strategy: type-guard

Type guard

fn has_metadata(e: &DirEntry) -> bool { !e.is_stdin() }

Try / catch

let md = if entry.is_stdin() { None } else { Some(entry.metadata()?) };

Prevention

When it happens

Trigger: Calling DirEntry::metadata() on an entry created from stdin (DirEntry::is_stdin() is true), e.g. when ripgrep searches '-' and downstream code asks for the entry's metadata.

Common situations: Custom code iterating WalkBuilder entries that unconditionally calls metadata() without checking is_stdin(); piping data via stdin to a tool that filters by file size.

Related errors


AI-assisted analysis of BurntSushi/ripgrep@3fce3b5bb0 (2026-08-06). Data as JSON: /data/errors/c9d4b3927309a4ec.json. Report an issue: GitHub.