elkowar/eww · error
Error opening log file
Error message
Error opening log file ({}), for writing What it means
When eww daemonizes (do_detach), it redirects stdout/stderr/stdin to a log file. This panic fires when the log file cannot be opened for writing with create+append options via std::fs::OpenOptions. It indicates the daemon could not set up its logging destination.
Solutions
- Check that the log file path exists and its parent directory is writable (create missing directories)
- Verify XDG_CACHE_HOME / EWW_LOG env vars point to valid writable locations
- Run `eww logs`-equivalent check or open the path manually to confirm permissions
- Run the daemon as a user with write access to the configured log path
Example fix
// before
std::fs::OpenOptions::new().create(true).append(true).open(&log_file_path)
.unwrap_or_else(|_| panic!("Error opening log file ({})", log_file_path.as_ref().to_string_lossy()));
// after
if let Some(parent) = log_file_path.as_ref().parent() {
std::fs::create_dir_all(parent)?;
}
let file = std::fs::OpenOptions::new().create(true).append(true).open(&log_file_path)
.with_context(|| format!("Error opening log file ({})", log_file_path.as_ref().to_string_lossy()))?; Defensive patterns
Strategy: fallback
Validate before calling
const path = getLogFilePath();
if (!fs.existsSync(path.dirname(path))) fs.mkdirSync(path.dirname(path), { recursive: true });
fs.accessSync(path.dirname(path), fs.constants.W_OK); Type guard
function isWritableDir(p) { try { fs.accessSync(p, fs.constants.W_OK); return fs.statSync(p).isDirectory(); } catch { return false; } } Try / catch
try { startDaemon(); } catch (e) { if (String(e).includes('Error opening log file')) { console.error('Log path unwritable:', e); process.exit(1); } throw e; } Prevention
- Ensure the log file's parent directory exists before daemonizing
- Check write permissions on XDG cache dirs
- Avoid overriding EWW_LOG/XDG_CACHE_HOME with invalid paths
- Run the daemon under a user with access to the log path
When it happens
Trigger: Calling `eww daemonize` (which runs do_detach via initialize_server) when the log file path's parent directory does not exist, the path is unwritable due to permissions, or the path is invalid on the filesystem.
Common situations: XDG_CACHE_HOME or EWW_LOG file environment overrides pointing to nonexistent directories; read-only cache directories; running eww under a user without write permission to the log location; selinux/apparmor restrictions.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- could not get default display
- OneToNElementsMap got into inconsistent state
- No root scope in graph
- Something went wrong unindenting the string
- Could not get default gtk theme
AI-assisted analysis of elkowar/eww@48f5aa8b37 (2026-09-08).
Data as JSON: /api/errors/a17cfbba3c13163c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/eww/src/server.rs:283
// detach from terminal
match unsafe { nix::unistd::fork()? } {
nix::unistd::ForkResult::Child => {
nix::unistd::setsid()?;
match unsafe { nix::unistd::fork()? } {
nix::unistd::ForkResult::Parent { .. } => std::process::exit(0),
nix::unistd::ForkResult::Child => {}
}
}
nix::unistd::ForkResult::Parent { .. } => {
return Ok(ForkResult::Parent);
}
}
let file = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&log_file_path)
.unwrap_or_else(|_| panic!("Error opening log file ({}), for writing", log_file_path.as_ref().to_string_lossy()));
let fd = file.as_raw_fd();
if nix::unistd::isatty(1)? {
nix::unistd::dup2(fd, std::io::stdout().as_raw_fd())?;
}
if nix::unistd::isatty(2)? {
nix::unistd::dup2(fd, std::io::stderr().as_raw_fd())?;
}
Ok(ForkResult::Child)
}
/// Ensure the log directory never grows larger than 100MB by deleting files older than 7 days,
/// and truncating all other logfiles to 100MB.
fn cleanup_log_dir(log_dir: impl AsRef<Path>) -> Result<()> {
// Find all files named "eww_*.log" in the log directory
let log_files = std::fs::read_dir(&log_dir)?
.filter_map(|entry| {View on GitHub (pinned to 48f5aa8b37)