jdx/mise · error
not a directory: {src_dir.display}
Error message
not a directory: {src_dir.display} What it means
build_layer_from_dir builds an OCI layer from a host directory, and first verifies that src_dir actually is a directory. This error is thrown when the given path does not exist or is a file/symlink to something that is not a directory.
Source
Thrown at src/oci/layer.rs:133
return Err(format!("{name} must not be empty"));
}
value
.parse::<u32>()
.map_err(|_| format!("{name} must be a non-negative integer <= {}", u32::MAX))
}
/// Build a reproducible gzipped tar layer from files in `src_dir`, placing them
/// under `target_prefix` inside the tar (e.g. `/mise/installs/node/20.0.0`).
///
/// `src_dir` must exist and be a directory. Symlinks are preserved; their
/// targets are NOT followed. `owner` is applied to every emitted tar entry.
pub(crate) fn build_layer_from_dir(
src_dir: &Path,
target_prefix: &str,
owner: LayerOwner,
) -> Result<LayerBlob> {
if !src_dir.is_dir() {
eyre::bail!("not a directory: {}", src_dir.display());
}
let entries = collect_sorted_entries(src_dir, false, owner, None)?;
build_layer_from_entries(&entries, target_prefix, owner, None)
}
/// Build a tool layer while rebasing host paths embedded by its installer.
pub(crate) fn build_relocated_tool_layer_from_dir(
src_dir: &Path,
target_prefix: &str,
owner: LayerOwner,
relocation: &ToolRelocation,
) -> Result<LayerBlob> {
if !src_dir.is_dir() {
eyre::bail!("not a directory: {}", src_dir.display());
}
let entries = collect_sorted_entries(src_dir, false, owner, Some(relocation))?;View on GitHub (pinned to afd2eddd3a)
Solutions
- Verify the path exists and is a directory: `ls -la <path>`; fix the path in the config or create the directory.
- If you intended to copy a single file, use the file-copy path (build_layer_from_path) rather than the directory variant.
- Check the working directory / relative path base the config is resolved against and use an absolute path if needed.
Example fix
// before
build_layer_from_dir(Path::new("assets/logo.png"), "app", owner)
// after
build_layer_from_dir(Path::new("assets"), "app", owner) Defensive patterns
Strategy: validation
Validate before calling
fn assert_dir(p: &Path) -> Result<()> {
if !p.is_dir() {
return Err(eyre!("not a directory: {}", p.display()));
}
Ok(())
}
assert_dir(&src_dir)?; Type guard
fn is_dir_or_fail(p: &Path) -> Option<&Path> {
if p.is_dir() { Some(p) } else { None }
} Try / catch
match build_layer_from_dir(&src, prefix, owner) {
Err(e) if e.to_string().starts_with("not a directory") => {
eprintln!("{} missing or not a dir — fix the path or use the file-copy path", src.display());
}
r => r,
} Prevention
- Check the path exists and is a directory before configuring a dir layer.
- Use absolute paths to avoid cwd-dependent resolution.
- Re-check paths after refactors/renames of the source tree.
When it happens
Trigger: Calling build_layer_from_dir (directly or via build_layer_from_path) with a path that is missing, a regular file, or a dangling symlink — `src_dir.is_dir()` returns false and the bail fires before collecting entries.
Common situations: Config pointing a copy/dir layer at a file instead of a directory; a path deleted or renamed since the config was written; relative path resolved from the wrong working directory; case-sensitivity mismatch on case-sensitive filesystems.
Related errors
- cannot copy a file or symlink to the image root
- copy image path {image_path:?} ends with `/` but {host_path.
- unsupported host path type: {host_path.display}
- not a directory: {}
- rustc output is not a regular file: {}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/dfe4cd2e2b1da5e6.
Report an issue: GitHub.