jdx/mise · error
{} is not a regular file or symlink
Error message
{} is not a regular file or symlink What it means
live_object snapshots a path's git object representation (blob or symlink target). If symlink_metadata reports the path is neither a regular file nor a symlink (e.g. fifo, socket, device, directory), there is no representable object and the function fails.
Source
Thrown at src/system/history/sync/apply.rs:803
}
pub(super) fn live_object(
repo: &crate::system::history::shadow::HistoryRepo,
path: &Path,
) -> Result<Option<Object>> {
let meta = match std::fs::symlink_metadata(path) {
Ok(meta) => meta,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),
Err(err) => return Err(err.into()),
};
if meta.file_type().is_symlink() {
return Ok(Some((
"120000".into(),
repo.transient_blob_id(std::fs::read_link(path)?.to_string_lossy().as_bytes())?,
)));
}
if !meta.is_file() {
bail!("{} is not a regular file or symlink", display_path(path));
}
#[cfg(unix)]
let executable = {
use std::os::unix::fs::PermissionsExt;
meta.permissions().mode() & 0o111 != 0
};
#[cfg(not(unix))]
let executable = false;
Ok(Some((
if executable { "100755" } else { "100644" }.into(),
repo.transient_blob_id(&std::fs::read(path)?)?,
)))
}
fn saved_object(
repo: &crate::system::history::shadow::HistoryRepo,
tracked: &TrackedSet,
path: &Path,View on GitHub (pinned to afd2eddd3a)
Solutions
- Inspect the path with `ls -la` and remove or replace the special file with a regular file or symlink.
- If the path should be a directory, resolve its type before pulling (see directory handling) rather than leaving a non-file node.
- Exclude paths that legitimately hold sockets/pipes from setup-history tracking.
Example fix
// before
mkfifo ~/.config/app/queue
// after
rm ~/.config/app/queue && echo '{}' > ~/.config/app/queue Defensive patterns
Strategy: validation
Validate before calling
let meta = std::fs::symlink_metadata(path)?;
if !(meta.is_file() || meta.file_type().is_symlink()) {
// resolve the special file before pulling
} Type guard
fn is_file_or_symlink(p: &Path) -> bool {
std::fs::symlink_metadata(p)
.map(|m| m.is_file() || m.file_type().is_symlink())
.unwrap_or(false)
} Prevention
- Keep sockets/fifos/pipes out of tracked directories
- Replace special files with regular files before syncing
- Audit managed paths with `find <dir> ! -type f ! -type l`
When it happens
Trigger: A path tracked by setup history was replaced by a special file (named pipe, socket, device node) or a directory; calling apply/Step/recover_step/hold_reason over such a path.
Common situations: A tool created a socket or fifo at a config path; a user replaced a managed file with a directory; container volume mounts exposing device nodes in a managed directory.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- cannot write task stub because {} is not a regular file
- {} changed during recovery; left untouched
- {} is not a directory; resolve its type before pulling
- {} changed after permission planning; retry pull
- {} changed during application; left untouched
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/ec9241b09c825e3e.
Report an issue: GitHub.