EpicGames/lore · critical
Failed to open log file
Error message
Failed to open log file {} What it means
setup_tracing initializes the tracing subscriber with a pretty log layer writing to a log file passed via CLI args. If std::fs::File::create cannot create/open the log file, the process panics immediately at startup because logging is considered essential. This is a fail-fast design: running without logs would make the chaos client unobservable.
Solutions
- Create the parent directory of the log file (e.g. mkdir -p) or correct the --log-file path.
- Check write permissions on the target directory and file.
- Choose a writable location such as a path under the user's home or temp directory.
- In code, handle the io::Error explicitly instead of unwrapping (fall back to stderr-only logging).
Example fix
// before
let log_file_layer = std::fs::File::create(&args.log_file)
.unwrap_or_else(|_| panic!("Failed to open log file {}", args.log_file));
// after
let log_file_layer = std::fs::File::create(&args.log_file)
.map_err(|e| anyhow::anyhow!("Failed to open log file {}: {e}", args.log_file))?; Defensive patterns
Strategy: try-catch
Validate before calling
if let Err(e) = std::fs::metadata(&args.log_file) { /* path may not exist; check parent */ }
if let Some(dir) = std::path::Path::new(&args.log_file).parent() {
std::fs::create_dir_all(dir)?;
} Type guard
fn log_file_writable(path: &str) -> bool {
std::path::Path::new(path).parent().map(|d| d.is_dir()).unwrap_or(false)
&& std::fs::OpenOptions::new().append(true).create(true).open(path).is_ok()
} Try / catch
match std::fs::File::create(&args.log_file) {
Ok(f) => init_with_file(f),
Err(e) => { eprintln!("log file unavailable ({}), falling back to stderr", e); init_stderr_only(); }
} Prevention
- Create the log directory before startup (create_dir_all).
- Validate the --log-file path in CLI parsing.
- Never panic on logging setup; degrade to stderr instead.
- Test the binary in a read-only-filesystem container.
When it happens
Trigger: Calling setup_tracing with CliArgs::log_file pointing to a path that cannot be created: non-existent parent directory, no write permission, path is a directory, read-only filesystem, or disk full.
Common situations: User passes --log-file /var/log/lore.log without root; typo'd path so the parent dir doesn't exist; container with read-only filesystem; log path colliding with an existing directory.
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
- {e}
- Networking not supported on this OS
- could not get available parallelism
- hex encode failed
- PresignTokenPayload is always serializable
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/2d575d0c32d45238.
Report an issue: GitHub.
Appendix: source
Thrown at lore-chaos-client/src/tracing.rs:13
// SPDX-FileCopyrightText: 2026 Epic Games, Inc.
// SPDX-License-Identifier: MIT
use tracing::level_filters::LevelFilter;
use tracing_subscriber::Layer;
use tracing_subscriber::fmt::layer;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use crate::cli::CliArgs;
pub fn setup_tracing(args: &CliArgs) {
let log_file_layer = std::fs::File::create(&args.log_file)
.unwrap_or_else(|_| panic!("Failed to open log file {}", args.log_file));
let log_layer = layer()
.pretty()
.with_writer(log_file_layer)
.with_ansi(false)
.with_filter(LevelFilter::INFO);
let stdout_filter = if args.log_to_console {
LevelFilter::INFO
} else {
LevelFilter::WARN
};
let stdout_layer = tracing_subscriber::fmt::layer().with_filter(stdout_filter);
tracing_subscriber::registry()
.with(log_layer)
.with(stdout_layer)
.init();View on GitHub (pinned to 074eb0b0d1)