Hmbown/CodeWhale · error
log file missing
Error message
log file missing: {} What it means
The `codewhale lane log` (tail) command resolves the lane via `LaneRegistry::open_default`, reads `lane.log_path`, and bails if that file does not exist before reading and splitting its content into lines. It is thrown because tailing a non-existent log is indistinguishable from an empty one and would silently show nothing. The error carries the missing path so the user can check the right location.
Solutions
- Run the lane once so its log file is created, then retry the log command.
- Verify the path shown in the error exists and matches the lane's configured log_path; fix the lane config if it points elsewhere.
- If the log was rotated/deleted, restore it or re-register the lane to regenerate the log.
- Check you are running on the same host/filesystem where the lane actually writes its log (containers, remote workers).
Example fix
// before: tail a lane that never started codewhale lane log my-lane --tail 50 // error: log file missing: /var/lib/codewhale/lanes/my-lane/log // after: start the lane first codewhale lane run my-lane codewhale lane log my-lane --tail 50
Defensive patterns
Strategy: try-catch
Validate before calling
let path = lane.log_path;
if !path.exists() {
eprintln!("skipping log tail: {} does not exist (lane never run?)", path.display());
return Ok(());
} Try / catch
match run_lane_log(&lane_id) {
Err(e) if e.to_string().contains("log file missing") => eprintln!("lane has no log yet; start it first"),
Err(e) => return Err(e),
Ok(v) => println!("{v}"),
} Prevention
- Start/verify the lane before tailing its log.
- Check the lane's log_path exists in health checks before invoking log commands.
- Account for log rotation and cleanup jobs in scripts.
When it happens
Trigger: Running a lane-log command whose `LaneRegistry::load(&lane_id)` returns a lane whose `log_path` does not exist on disk at invocation time (`!path.exists()`).
Common situations: The lane was registered but never run, the log file was deleted or rotated away, the lane points at a path on another machine/container volume, or a typo in config points the lane at a stale path.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- already exists; pass --force to overwrite it
- Cannot resolve current binary path
- inline stderr logger panicked
- inline stdout logger panicked
- lane log proxy requires a command
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8226fcc4e3e25153.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/lib.rs:997
println!("{attach}");
bail!("tmux attach unavailable");
}
}
} else {
println!("{attach}");
Ok(())
}
}
LaneCommand::Logs {
lane_id,
follow,
tail,
} => {
let reg = LaneRegistry::open_default()?;
let lane = reg.load(&lane_id)?;
let path = lane.log_path;
if !path.exists() {
bail!("log file missing: {}", path.display());
}
let content = std::fs::read(&path)?;
let lines: Vec<&[u8]> = content
.split(|byte| *byte == b'\n')
.filter(|line| !line.is_empty())
.collect();
let start = lines.len().saturating_sub(tail);
let mut stdout = std::io::stdout().lock();
for line in &lines[start..] {
stdout.write_all(String::from_utf8_lossy(line).as_bytes())?;
stdout.write_all(b"\n")?;
}
stdout.flush()?;
if !follow {
return Ok(());
}
let mut file = std::fs::File::open(&path)?;
file.seek(std::io::SeekFrom::End(0))?;View on GitHub (pinned to 73e0f67d83)