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

  1. Re-fetch or republish the remote tree entry; the stored node metadata is invalid.
  2. Re-run the task to regenerate a clean output tree in the remote cache.
  3. Check the uploader code for paths that keep trailing separators or embed multiple components.
  4. 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

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


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)