jdx/mise · error
[dotfiles]."{req.target_raw}": target is not a safe OCI path
Error message
[dotfiles]."{req.target_raw}": target is not a safe OCI path What it means
Before building a dotfiles OCI layer, each requested target path is normalized (absolute, forward slashes) and validated. This error is thrown when the resulting path is empty or any component is '..', because such paths would escape or be meaningless inside the image root and could enable path traversal in the OCI layer.
Source
Thrown at src/oci/builder.rs:1099
(files, dirs)
}
}
fn oci_target_path(req: &FileRequest) -> Result<String> {
let raw = req.target_raw.as_str();
let path = if raw == "~" {
"root".to_string()
} else if let Some(rest) = raw.strip_prefix("~/") {
format!("root/{rest}")
} else {
req.target
.strip_prefix("/")
.map_err(|_| eyre::eyre!("dotfile target must be absolute: {}", req.target_raw))?
.to_string_lossy()
.replace('\\', "/")
};
if path.is_empty() || path.split('/').any(|p| p == "..") {
bail!(
"[dotfiles].\"{}\": target is not a safe OCI path",
req.target_raw
);
}
Ok(path)
}
fn source_mode(path: &std::path::Path) -> Result<u32> {
let md = path.metadata()?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
Ok(md.permissions().mode() & 0o7777)
}
#[cfg(not(unix))]
{
let _ = md;
Ok(0o644)View on GitHub (pinned to afd2eddd3a)
Solutions
- Replace '..' components in the dotfile target with an absolute path rooted at '/' (or the correct home-relative location).
- Ensure the target is a non-empty absolute path, e.g. target = "/home/user/.zshrc" not "/" or "../x".
- If you intended a path outside the image via traversal, restructure the image so the file lives under a real prefix instead.
Example fix
// before [[dotfiles]] source = "zshrc" target = "../.zshrc" // after [[dotfiles]] source = "zshrc" target = "/home/user/.zshrc"
Defensive patterns
Strategy: validation
Validate before calling
fn is_safe_oci_path(target: &str) -> bool {
let path = target.strip_prefix('/').unwrap_or(target);
!path.is_empty() && !path.split('/').any(|p| p == "..")
}
assert!(is_safe_oci_path("/home/user/.zshrc")); Try / catch
match oci_target_path(&req) {
Err(e) if e.to_string().contains("not a safe OCI path") => {
eprintln!("rewrite target without '..' and as absolute path: {}", req.target_raw);
}
p => p,
} Prevention
- Always write dotfile targets as absolute paths with no '..' components.
- Validate targets in CI before building images.
- Avoid templated targets that can expand to empty strings.
When it happens
Trigger: Calling build_dotfiles_layer with a req.target_raw that either becomes empty after stripping the leading '/' (e.g. target "/"), or contains a '..' component in any path segment (e.g. "~/../etc/passwd" or "/etc/../secret").
Common situations: Mistyped dotfile targets like "~/..", templated targets that expand to empty, copy-pasted relative paths such as "../dotfiles/zshrc", or targets using '..' to redirect outside the home directory.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- [dotfiles]."{}": source does not exist: {}
- [dotfiles]."{}": mode symlink-each requires a directory sour
- [dotfiles]."{}": target is not a safe OCI path
- {target_raw}: target must be absolute or start with ~/
- [dotfiles]."{req.target_raw}": source does not exist: {req.s
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/baa3c1d2336beeb9.
Report an issue: GitHub.