BoundaryML/baml · error · LogError
IO error
Error message
IO error: {0} What it means
Generic IO-error variant of the logging error type in baml-log: any filesystem or stream failure encountered while writing to the configured log file (or switching log output) is wrapped in this variant, with the underlying io::Error carried in {0}. It fires from the logger's file-writing path when LOG_FILE is set, not from application logic itself.
Solutions
- Check the log destination path exists and is writable (permissions, disk space)
- Wrap logger calls to handle LogError::Io and fall back to a safe sink
- If piping logs, ensure the downstream reader stays alive
- Re-create the log file/directory if it was deleted while running
Example fix
// before
logger.write(record).unwrap();
// after
if let Err(LogError::Io(e)) = logger.write(record) {
eprintln!("logging disabled: {e}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify log destination is writable before initializing the logger let f = std::fs::OpenOptions::new().append(true).create(true).open(log_path)?; assert_writable(&f.metadata()?);
Type guard
fn is_io_err(e: &LogError) -> bool { matches!(e, LogError::Io(_)) } Try / catch
match logger.write(record) {
Err(LogError::Io(e)) => eprintln!("log write failed: {e}"),
Err(other) => return Err(other),
Ok(_) => {}
} Prevention
- Monitor disk space and permissions for log directories
- Avoid piping logs to short-lived readers
- Handle LogError::Io explicitly instead of unwrapping
When it happens
Trigger: Log writes fail at the OS level: the log file/destination cannot be written (disk full, closed pipe, permission denied, flushed writer failing) when the logger emits a record.
Common situations: Logging to a file whose directory was removed or is read-only; disk quota exceeded; logging to a stdout/stderr pipe whose reader exited (broken pipe); network file systems dropping writes.
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
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/57e6274737664c21.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-lib/baml-log/src/logger.rs:411
max_message_length: self.max_message_length,
running_in_lsp: self.running_in_lsp,
}
}
}
lazy_static! {
/// Thread-safe configuration with runtime modification support
static ref CONFIG: RwLock<LogConfig> = RwLock::new(LogConfig::from_env());
static ref LOGGED_LINES: RwLock<HashSet<(Option<String>, Option<String>, Option<u32>)>> = RwLock::new(HashSet::new());
/// Optional log file path — when set, log output goes to this file instead of stdout.
static ref LOG_FILE: Mutex<Option<PathBuf>> = Mutex::new(None);
}
/// Error type for logging operations
#[derive(Debug, Error)]
pub enum LogError {
/// Error writing to output
#[error("IO error: {0}")]
Io(#[from] io::Error),
/// Error serializing to JSON
#[error("JSON serialization error: {0}")]
Json(#[from] serde_json::Error),
/// Error acquiring lock
#[error("Failed to acquire lock")]
LockError,
/// Configuration error
#[error("Configuration error: {0}")]
Config(String),
}
// /// JSON-serializable log entry
// #[derive(Serialize)]
// struct LogEntry<'a> {View on GitHub (pinned to bd85ce9dee)