jdx/mise · error
remote task path is not a regular file or directory: {}
Error message
remote task path is not a regular file or directory: {} What it means
After mise clones a remote-tasks git repository, prepare_remote_path() chmods fetched regular files and leaves directories intact. It stats with symlink_metadata, so a symlink - which is neither a regular file nor a directory to lstat - bails with 'remote task path is not a regular file or directory'. The same applies to any other special file type found where a task file is expected.
Source
Thrown at src/task/task_file_providers/remote_task_git.rs:80
Self {
url_without_path: url_without_path.to_string(),
path: path.to_string(),
branch,
}
}
}
impl RemoteTaskGit {
/// Make fetched task files executable while leaving task include directories intact.
fn prepare_remote_path(path: &PathBuf) -> Result<()> {
let metadata = path.symlink_metadata()?;
if metadata.file_type().is_file() {
return file::make_executable(path);
}
if metadata.file_type().is_dir() {
return Ok(());
}
eyre::bail!(
"remote task path is not a regular file or directory: {}",
display_path(path)
)
}
fn get_cache_key(&self, repo_structure: &GitRepoStructure) -> String {
let key = format!(
"{}{}",
repo_structure.url_without_path,
repo_structure.branch.to_owned().unwrap_or("".to_string())
);
hash::hash_sha256_to_str(&key)
}
fn get_repo_structure(&self, file: &str) -> GitRepoStructure {
RemoteSource::parse_git(file)
.map(|source| source.into())
.unwrap()View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Replace the symlink with the real file (or a copy) in the tasks repo and commit it
- Duplicate shared task files instead of symlinking them
- Use mise's task include mechanisms rather than filesystem links
Example fix
# before: tasks/deploy.sh is a symlink ln -s ../shared/deploy.sh tasks/deploy.sh # after: a real file cp ../shared/deploy.sh tasks/deploy.sh
Defensive patterns
Strategy: validation
Validate before calling
// lint the tasks repo so symlinks never reach prepare_remote_path:
for entry in walkdir::WalkDir::new(&tasks_dir).follow_links(false) {
let e = entry?;
if !e.file_type().is_file() && !e.file_type().is_dir() {
return Err(eyre::bail!("non-regular task path: {}", e.path().display()));
}
} Type guard
fn is_regular_or_dir(path: &std::path::Path) -> bool {
path.symlink_metadata()
.map(|m| m.file_type().is_file() || m.file_type().is_dir())
.unwrap_or(false)
} Try / catch
match fetch_remote_tasks(&source).await {
Ok(tasks) => tasks,
Err(err) if err.to_string().contains("not a regular file or directory") => {
eprintln!("replace the symlinked task file in {} with a real file", source.repo);
Err(err) // a config/repo fix is required; retrying changes nothing
}
Err(err) => return Err(err),
} Prevention
- Commit real files, not symlinks, in remote-task repositories
- Add a CI lint that rejects symlinks inside the tasks directory
- Share task logic via includes or duplicated files, not filesystem links
- If symlinks are required for local dev, keep them out of the synced tasks dir
When it happens
Trigger: The remote tasks repository contains a symlink where a task file or include path is expected; on checkout (Linux/macOS, or Windows with core.symlinks=true) the path is a real symlink and prepare_remote_path rejects it when making task files executable.
Common situations: Monorepos sharing one task file between packages via symlink; a symlinked directory of tasks; repos where a setup script linked files into the tasks directory.
Related errors
- too many symlinks while resolving atomic write target: {}
- refusing to remove non-link: {}
- install from exe
- cannot write task stub because {} is a symbolic link
- cannot link {} to its own install path
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/0f7a1055d3a87bcb.
Report an issue: GitHub.