facebook/flow · error
PidLog::log: failed to write
Error message
PidLog::log: failed to write
What it means
Panics when writeln! to the already-opened pids log fails. The pid log records every flow process PID and reason so orphaned daemons can be detected and killed later; the writer is a lazily-initialized global behind a mutex (pid_log::init opens the file). Note that no_fail=true only suppresses the 'uninitialized writer' panic, not a failed write.
Source
Thrown at rust_port/crates/flow_daemon/src/pid_log.rs:61
.write(true)
.open(pids_file)?;
*guard = Some(oc);
Ok(())
})
}
pub fn log(reason: Option<&str>, no_fail: bool, pid: u32) {
if !*enabled().lock().expect("pid_log enabled mutex poisoned") {
return;
}
let pid = sys_utils::pid_of_handle(pid);
let reason = reason.unwrap_or("unknown");
let mut guard = log_oc().lock().expect("pid_log log_oc mutex poisoned");
match guard.as_mut() {
None if no_fail => {}
None => panic!("Can't write pid to uninitialized pids log"),
Some(oc) => {
writeln!(oc, "{}\t{}", pid, reason).expect("PidLog::log: failed to write");
oc.flush().expect("PidLog::log: failed to flush");
}
}
}
#[derive(Debug)]
pub struct FailedToGetPids;
impl std::fmt::Display for FailedToGetPids {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "FailedToGetPids")
}
}
impl std::error::Error for FailedToGetPids {}
pub fn get_pids(pids_file: &Path) -> Result<Vec<(u32, String)>, FailedToGetPids> {
let ic = File::open(pids_file).map_err(|_| FailedToGetPids)?;View on GitHub (pinned to f88ac94bcf)
Solutions
- Free space on the volume holding the pids file and let the process log again
- Point the pids file at a stable local path (pid_log::init argument) not subject to rotation or unmounting
- If the write error is from a moved/truncated file, restart the process so init reopens a fresh handle
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the pids-log target still accepts writes before relying on it
let probe = pids_file.with_extension("probe");
if std::fs::write(&probe, b"x").is_err() {
// volume full/unwritable: skip enabling the pid log rather than crash later
pid_log::disable();
}
std::fs::remove_file(&probe).ok(); Prevention
- Keep the pids file on local, non-rotated storage
- Remember no_fail=true only bypasses the uninitialized case; it does not guard write errors
- Free disk space on the volume holding the pids log before restarting long-lived processes
When it happens
Trigger: Calling pid_log::log after the disk holding the pids file is full; the log file was truncated/moved out from under the open handle (log rotation); the filesystem with the pids file was unmounted (NFS/sshfs home) while the process ran.
Common situations: Long-lived flow daemons on CI boxes with full disks; pids.log on a network mount that dropped; external log rotation tools moving the file.
Related errors
- PidLog::log: failed to flush
- Daemon::set_context: bincode serialize context
- failed to write {}: {}
- Daemon::flush failed
- failed to write flowlib file
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/5daf57df5dda5e12.
Report an issue: GitHub.