ClementTsang/bottom · warning · anyhow::Error

missing device

Error message

missing device

What it means

Partition::from_str parses a line from /proc/mounts (or /etc/mtab) via splitn(5, ' '). This error fires when the line has no first token at all (i.e. an empty line), so no device field can be extracted.

Solutions

  1. Filter out empty lines before parsing each mount entry
  2. Trim and skip blank lines when reading /proc/mounts
  3. Check the mounts file source isn't truncated or unreadable

Example fix

// before
for line in content.lines() {
    let p = Partition::from_str(line)?;
// after
for line in content.lines().filter(|l| !l.trim().is_empty()) {
    let p = Partition::from_str(line)?;
Defensive patterns

Strategy: validation

Validate before calling

// Skip blank lines before parsing mounts entries
let entries: Vec<Partition> = std::fs::read_to_string("/proc/mounts")?
    .lines()
    .filter(|l| !l.trim().is_empty())
    .filter_map(|l| Partition::from_str(l).ok())
    .collect();

Try / catch

match Partition::from_str(line) {
    Ok(p) => Some(p),
    Err(e) => { log::debug!("skipping line: {e}"); None },
}

Prevention

When it happens

Trigger: Calling Partition::from_str with an empty or whitespace-only string, which happens when reading /proc/mounts yields blank lines.

Common situations: Reading mount tables that end with a trailing newline, or passing empty input from a custom mounts source.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of ClementTsang/bottom@b77d317502 (2026-09-07). Data as JSON: /api/errors/a21ecfde2a0fc90b. Report an issue: GitHub.

Appendix: source

Thrown at src/collection/disks/unix/linux/partition.rs:130

    s.replace(ESCAPED_BACKSLASH, "\\")
        .replace(ESCAPED_SPACE, " ")
        .replace(ESCAPED_TAB, "\t")
        .replace(ESCAPED_NEWLINE, "\n")
}

impl FromStr for Partition {
    type Err = anyhow::Error;

    fn from_str(line: &str) -> anyhow::Result<Partition> {
        // Example: `/dev/sda3 /home ext4 rw,relatime,data=ordered 0 0`
        let mut parts = line.trim_start().splitn(5, ' ');

        let device = match parts.next() {
            Some("none") => None,
            Some(device) => Some(device.to_string()),
            None => {
                bail!("missing device");
            }
        };

        let mount_point = match parts.next() {
            Some(mount_point) => PathBuf::from(fix_mount_point(mount_point)),
            None => {
                bail!("missing mount point");
            }
        };
        let fs_type = match parts.next() {
            Some(fs) => FileSystem::from_str(fs)?,
            _ => {
                bail!("missing filesystem type");
            }
        };

        Ok(Partition {
            device,

View on GitHub (pinned to b77d317502)