astrid-runtime/astrid · error · std::io::Error::InvalidData
legacy REPL history is not a regular file: {}
Error message
legacy REPL history is not a regular file: {} What it means
migrate_legacy_history moves an old REPL history file into the new operator log location, but refuses to touch anything that is not a plain regular file. If symlink_metadata shows the legacy path is a symlink, directory, device, or otherwise non-regular, it fails closed with InvalidData so commands are never silently lost through an unsafe migration.
Source
Thrown at crates/astrid-cli/src/repl.rs:213
Err(ReadlineError::Eof | _) => {
// Ctrl+D or any I/O error → EOF.
return ReadlineEvent::Eof;
},
}
}
}
}
/// Move the legacy operator history out of the retired top-level Astrid root.
///
/// The old file is accepted only as a regular, no-follow file and is bounded
/// before being copied. If both locations exist, differing bytes fail closed;
/// an operator must resolve the ambiguity rather than silently lose commands.
fn migrate_legacy_history(new_path: &Path, legacy_path: &Path) -> io::Result<()> {
let legacy_exists = match std::fs::symlink_metadata(legacy_path) {
Ok(metadata) => {
if metadata.file_type().is_symlink() || !metadata.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy REPL history is not a regular file: {}",
legacy_path.display()
),
));
}
astrid_core::platform_fs::verify_no_redirects(legacy_path)?;
true
},
Err(error) if error.kind() == io::ErrorKind::NotFound => false,
Err(error) => return Err(error),
};
if !legacy_exists {
return Ok(());
}
let legacy = read_history_bounded(legacy_path)?;
match std::fs::symlink_metadata(new_path) {View on GitHub (pinned to affd8760f4)
Solutions
- Remove the symlink/non-regular file at the legacy history path and either restore a real history file or let migration start fresh
- If using dotfile symlinks, replace the symlink with a real file (copy the target contents) before running the CLI
- Point the operator at the actual file location so nothing is lost, then delete the legacy symlink
Example fix
// before: ~/.astrid/history -> /dotfiles/history (symlink) causes failure // after rm ~/.astrid/legacy-history && cp /dotfiles/history ~/.astrid/legacy-history
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the legacy history path before triggering migration
fn legacy_history_is_regular(p: &std::path::Path) -> std::io::Result<bool> {
Ok(std::fs::symlink_metadata(p)
.map(|m| m.is_file() && !m.file_type().is_symlink())
.unwrap_or(true)) // nonexistent is fine (nothing to migrate)
} Type guard
fn is_regular_file(m: &std::fs::Metadata) -> bool {
m.is_file() && !m.file_type().is_symlink()
} Try / catch
match std::fs::symlink_metadata(legacy_path) {
Ok(m) if !m.is_file() || m.file_type().is_symlink() => {
eprintln!("Resolve {}: symlinked/non-regular legacy history must be replaced with a real file", legacy_path.display());
}
_ => { /* safe to run REPL */ }
} Prevention
- Do not symlink REPL history files; use copies or hardlinks instead
- Check `ls -la` on history paths after restoring backups
- Ensure no directory or fifo ever occupies the legacy history path
When it happens
Trigger: Calling migrate_legacy_history (via Repl::new) when the legacy history path exists but is a symlink or not a regular file (e.g. a directory or fifo at the legacy history location).
Common situations: User symlinked their old history file elsewhere (common for dotfile management); a directory was accidentally created at the history path; devtools/tests place a fifo at the path.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- legacy and operator REPL histories differ; refusing to merge
- legacy capsule directory is not a regular directory: {}
- legacy capsule entry is not a regular directory: {}
- REPL history path is not a regular file: {}
- layout migration destination is redirected or not a regular
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/b332cb6957e5d5b3.
Report an issue: GitHub.