{"record":{"id":"ec9241b09c825e3e","repo":"jdx/mise","slug":"is-not-a-regular-file-or-symlink","errorCode":null,"errorMessage":"{} is not a regular file or symlink","messagePattern":"(.+?) is not a regular file or symlink","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/apply.rs","lineNumber":803,"sourceCode":"}\n\npub(super) fn live_object(\n    repo: &crate::system::history::shadow::HistoryRepo,\n    path: &Path,\n) -> Result<Option<Object>> {\n    let meta = match std::fs::symlink_metadata(path) {\n        Ok(meta) => meta,\n        Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),\n        Err(err) => return Err(err.into()),\n    };\n    if meta.file_type().is_symlink() {\n        return Ok(Some((\n            \"120000\".into(),\n            repo.transient_blob_id(std::fs::read_link(path)?.to_string_lossy().as_bytes())?,\n        )));\n    }\n    if !meta.is_file() {\n        bail!(\"{} is not a regular file or symlink\", display_path(path));\n    }\n    #[cfg(unix)]\n    let executable = {\n        use std::os::unix::fs::PermissionsExt;\n        meta.permissions().mode() & 0o111 != 0\n    };\n    #[cfg(not(unix))]\n    let executable = false;\n    Ok(Some((\n        if executable { \"100755\" } else { \"100644\" }.into(),\n        repo.transient_blob_id(&std::fs::read(path)?)?,\n    )))\n}\n\nfn saved_object(\n    repo: &crate::system::history::shadow::HistoryRepo,\n    tracked: &TrackedSet,\n    path: &Path,","sourceCodeStart":785,"sourceCodeEnd":821,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/sync/apply.rs#L785-L821","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nmkfifo ~/.config/app/queue\n// after\nrm ~/.config/app/queue && echo '{}' > ~/.config/app/queue","handlingStrategy":"validation","validationCode":"let meta = std::fs::symlink_metadata(path)?;\nif !(meta.is_file() || meta.file_type().is_symlink()) {\n    // resolve the special file before pulling\n}","typeGuard":"fn is_file_or_symlink(p: &Path) -> bool {\n    std::fs::symlink_metadata(p)\n        .map(|m| m.is_file() || m.file_type().is_symlink())\n        .unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["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`"],"tags":["filesystem","file-type","sync"],"backgroundTag":"type-mismatch","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}