espanso/espanso · error
unable to set up log output file
Error message
unable to set up log output file
What it means
After config loading, main attaches a log output file in the runtime directory via log_proxy.set_output_file(...).expect(...). The expect fires if opening/creating the log file fails or if the FileProxy lock is poisoned (error 143 path).
Source
Thrown at espanso/src/main.rs:625
info!("using runtime dir: {:?}", paths.runtime.display());
log_system_info();
if handler.requires_config {
let config_result = load_config(&paths.config).expect("unable to load config");
cli_args.config_store = Some(config_result.config_store);
cli_args.match_store = Some(config_result.match_store);
cli_args.non_fatal_errors = config_result.non_fatal_errors;
}
if handler.enable_logs {
log_proxy
.set_output_file(
&paths.runtime.join(LOG_FILE_NAME),
handler.log_mode == LogMode::Read,
handler.log_mode == LogMode::CleanAndAppend,
)
.expect("unable to set up log output file");
}
cli_args.paths = Some(paths);
}
// try to invoke `kdotool` to see if you have it or not.
#[cfg(target_os = "linux")]
if Command::new("kdotool")
.arg("getactivewindow")
.arg("getwindowclassname")
.output()
.is_ok()
{
} else {
info!("kdotool missing or not available for the current wayland DE.");
}
if let Some(args) = matches.subcommand_matches(&handler.subcommand) {View on GitHub (pinned to e6c3736675)
Solutions
- Recreate the runtime directory and fix permissions (`espanso path` shows it; typically `mkdir -p <runtime>` and chown to the running user).
- Check disk space (df -h) if the filesystem is full.
- Run espanso as the same user that owns the runtime dir; avoid mixing sudo/non-sudo runs.
- Verify the earlier panic (if 'unable to obtain FileProxy lock' preceded this) and fix its root cause.
- Update or patch espanso to degrade gracefully (keep memory-only logging) when the file can't be opened.
Example fix
// before
log_proxy
.set_output_file(&paths.runtime.join(LOG_FILE_NAME), read, clean)
.expect("unable to set up log output file");
// after
if let Err(err) = log_proxy.set_output_file(&paths.runtime.join(LOG_FILE_NAME), read, clean) {
eprintln!("warning: falling back to memory logging: {err}");
} Defensive patterns
Strategy: fallback
Validate before calling
let log_path = paths.runtime.join(LOG_FILE_NAME);
if let Err(e) = std::fs::OpenOptions::new().append(true).create(true).open(&log_path) {
eprintln!("cannot write log file {}: {e}", log_path.display());
} Try / catch
if let Err(e) = log_proxy.set_output_file(&log_path, read, clean) {
eprintln!("warning: memory-only logging: {e}");
} Prevention
- Ensure the runtime dir exists and is writable by the espanso user
- Avoid mixing sudo and normal-user runs (ownership drift)
- Monitor disk space on the runtime filesystem
- Fix preceding panics that can poison the log mutex
When it happens
Trigger: set_output_file returns Err: the runtime directory doesn't exist, is read-only, or denies write permission; disk full; or the underlying Mutex is poisoned from an earlier panic (LogMode::Read / CleanAndAppend flags passed from the handler).
Common situations: Runtime dir deleted or mounted read-only (sandboxed/Flatpak setups, read-only /run), permission mismatch after running espanso as different users, disk-full, or a prior panic poisoning the log mutex.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- unable to read input file
- unable to read input file
- unable to initialize engine
- unable to obtain FileProxy lock
- unable to initialize logs
AI-assisted analysis of espanso/espanso@e6c3736675 (2026-09-06).
Data as JSON: /api/errors/69951eba95e7c9d4.
Report an issue: GitHub.