jdx/mise · error
invalid remote cache path component
Error message
invalid remote cache path component
What it means
cache_name extracts the final file name of a cache path for use as a directory entry name and rejects empty names, '.', '..' and names containing '/' or NUL. The path must resolve to a single usable component for building the local materialized tree.
Solutions
- Re-fetch or republish the remote tree entry; the stored node metadata is invalid.
- Re-run the task to regenerate a clean output tree in the remote cache.
- Check the uploader code for paths that keep trailing separators or embed multiple components.
- Purge the offending cache key from the remote cache server.
Example fix
// before: node path with trailing slash passed to cache_name
let name = cache_name(Path::new("out/dir/"))?;
// after: normalize before building nodes
let name = cache_name(Path::new("out/dir"))?; Defensive patterns
Strategy: validation
Validate before calling
fn name_ok(p: &std::path::Path) -> bool {
match p.file_name().and_then(|n| n.to_str()) {
Some(n) => !(n.is_empty() || n == "." || n == ".." || n.contains(['/', '\0'])),
None => false,
}
} Type guard
fn is_single_name(p: &std::path::Path) -> bool {
p.file_name().map(|n| n != std::ffi::OsStr::new("") && n != "." && n != "..").unwrap_or(false)
} Try / catch
let name = cache_name(&node_path)
.map_err(|e| eyre!("remote tree node {node_path:?} unusable ({e}); republish entry"))?; Prevention
- Normalize node paths (trim trailing '/') before uploading tree metadata.
- Use UTF-8, single-segment names for tree nodes.
- Reject NUL bytes and separators when generating node names.
- Validate entries at upload time, not only download time.
When it happens
Trigger: build_directory() calls cache_name() on a tree node path whose file_name is empty, non-UTF-8-adjacent segment like '.', '..', or containing '/' or a NUL byte (task_cache_store.rs:522).
Common situations: Corrupt remote tree metadata produced by a buggy uploader; paths ending in '/' handled as directory nodes with empty names; malicious entries embedding separators; binaries/non-UTF-8 names written by non-mise clients.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- remote cache path must be relative
- action prediction payload is too large
- bootstrap_command returned an unsafe mise path
- brew-cask: command_wrapper requires a command name without…
- cached rustc output set is incomplete
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/2c03875a8bbf2654.
Report an issue: GitHub.
Appendix: source
Thrown at src/task/task_cache_store.rs:522
}
if path.components().any(|component| {
matches!(
component,
Component::ParentDir | Component::RootDir | Component::Prefix(_)
)
}) {
bail!("remote cache path escapes its output root");
}
Ok(())
}
fn cache_name(path: &Path) -> Result<String> {
let name = path
.file_name()
.and_then(|name| name.to_str())
.ok_or_else(|| eyre!("remote cache paths must be valid UTF-8"))?;
if name.is_empty() || name == "." || name == ".." || name.contains(['/', '\0']) {
bail!("invalid remote cache path component");
}
Ok(name.to_string())
}
fn validate_cache_name(name: &str) -> Result<()> {
let path = Path::new(name);
if name.is_empty()
|| name == "."
|| name == ".."
|| name.contains(['/', '\\', '\0'])
|| path.components().count() != 1
|| !matches!(path.components().next(), Some(Component::Normal(_)))
{
bail!("invalid remote cache path component");
}
Ok(())
}
View on GitHub (pinned to 533346cc37)