nikivdev/code · error

Error reading log file: {}

Error message

Error reading log file: {}

What it means

In tail_follow, the loop reading the log file bails if a read(2) on the log file fails (Err(e) from read). This surfaces OS-level read errors — not EOF, which is handled by polling — such as the file being deleted/truncated underneath the tailer or a permission change.

Source

Thrown at src/processes.rs:565

    let mut file = File::open(path).context("failed to open log file")?;
    file.seek(SeekFrom::End(0))?;

    if !quiet {
        println!("\n--- Following {} (Ctrl+C to stop) ---", path.display());
    }

    let mut buf = vec![0u8; 4096];
    loop {
        match file.read(&mut buf) {
            Ok(0) => {
                // No new data, sleep and retry
                thread::sleep(Duration::from_millis(100));
            }
            Ok(n) => {
                print!("{}", String::from_utf8_lossy(&buf[..n]));
            }
            Err(e) => {
                bail!("Error reading log file: {}", e);
            }
        }
    }
}

/// Fetch and display logs for a hub task by ID
fn show_hub_task_logs(task_id: &str, follow: bool) -> Result<()> {
    use reqwest::blocking::Client;
    use serde::Deserialize;

    const HUB_HOST: &str = "127.0.0.1";
    const HUB_PORT: u16 = 9050;

    #[derive(Debug, Deserialize)]
    struct TaskLog {
        id: String,
        name: String,
        command: String,

View on GitHub (pinned to a747e741ae)

Solutions

  1. Check the file still exists and is readable: `ls -l <log_path>`; recreate or restore permissions if needed.
  2. If log rotation caused it, restart `f logs --follow` after rotation completes.
  3. Look at the underlying OS error in the message (e.g. 'No such file or directory', 'Permission denied') and address that cause.
  4. Rerun the logs command to reopen the file once the filesystem state is sane.

Example fix

// before
Err(e) => {
    bail!("Error reading log file: {}", e);
}
// after
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
    // log rotated/deleted: wait for it to reappear instead of dying
    thread::sleep(Duration::from_millis(100));
    continue;
}
Err(e) => {
    bail!("Error reading log file: {}", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the log file is readable and stable before tailing
let meta = std::fs::metadata(&log_path)?;
if meta.len() == 0 { /* may still appear; proceed */ }
let f = std::fs::File::open(&log_path)?;

Try / catch

match tail_follow(&log_path) {
    Ok(()) => (),
    Err(e) if e.to_string().contains("Error reading log file") => {
        eprintln!("log vanished or I/O error: {e}; reattaching...");
        // reopen and retry once
        tail_follow(&log_path)?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: While following a log, the file read returns an error: file deleted (on filesystems where deletion still yields errors via the open handle it usually becomes EOF, but truncation/rotation can error), descriptor closed, or I/O error from the filesystem (EIO, EACCES after chmod).

Common situations: Log rotation that truncates or replaces the file mid-follow, another process deleting the log, disk errors, or permissions tightened while the process runs.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/403035382f99f6c3. Report an issue: GitHub.