jdx/mise · error

brew-cask: : git only_path must name a directory within the…

Error message

brew-cask:{}: git only_path must name a directory within the checkout

What it means

After validating only_path syntax, `git_only_path_source` canonicalizes clone_dir.join(only_path) and requires that the result is inside the canonical clone root AND is a directory. If the resolved path escapes the checkout (e.g. via symlinks) or points at a file rather than a directory, this error is thrown because only staging a directory subtree is supported.

Solutions

  1. Point only_path at a directory that exists in the current repository layout
  2. If you need a single file, stage its containing directory instead
  3. Update the cask stanza after upstream repository restructuring

Example fix

// before
cask "repo/x", only_path: "bin/tool"
// after
cask "repo/x", only_path: "share/tool"
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the target is a directory inside the checkout
let root = std::fs::canonicalize(clone_dir)?;
let src = std::fs::canonicalize(clone_dir.join(only_path))?;
if !src.starts_with(&root) || !src.is_dir() {
    eprintln!("only_path must resolve to a directory within the checkout");
}

Prevention

When it happens

Trigger: fetch_git_clone_and_stage passes an only_path that canonicalizes outside the clone root (symlink escape) or resolves to a regular file instead of a directory within the cloned repository.

Common situations: A cask's only_path references a single file, not a directory; the repository restructured and the old subdirectory no longer exists or was replaced by a symlink; typo in the subdirectory name.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/bfb3e16d2a4640ad. Report an issue: GitHub.

Appendix: source

Thrown at src/system/packages/brew/cask/fetch.rs:223

        || only_path
            .components()
            .any(|component| matches!(component, Component::ParentDir | Component::Prefix(_)))
    {
        bail!(
            "brew-cask:{}: git only_path must stay within the checkout",
            cask.token
        );
    }
    let clone_root = clone_dir.canonicalize()?;
    let source = clone_dir.join(only_path).canonicalize().wrap_err_with(|| {
        format!(
            "brew-cask:{}: git only_path does not exist: {}",
            cask.token,
            only_path.display()
        )
    })?;
    if !source.starts_with(&clone_root) || !source.is_dir() {
        bail!(
            "brew-cask:{}: git only_path must name a directory within the checkout",
            cask.token
        );
    }
    Ok(source)
}

pub(super) async fn fetch_archive(cask: &Cask, pr: Option<&dyn SingleReport>) -> Result<PathBuf> {
    let filename = archive_filename(&cask.url)
        .ok_or_else(|| eyre!("brew-cask:{}: URL has no file name", cask.token))?;
    let cache_dir = crate::dirs::CACHE.join("system-brew").join("casks");
    file::create_dir_all(&cache_dir)?;
    let url_hash = &hash::hash_sha256_to_str(&cask.url)[..12];
    let archive = cache_dir.join(format!(
        "{}-{}-{url_hash}-{filename}",
        cask.token, cask.version
    ));
    if !archive.exists() {

View on GitHub (pinned to 533346cc37)