jdx/mise · error

brew-cask: structured copy source

Error message

brew-cask: structured copy source '{}' was not found

What it means

The copy step's source resolved to exactly one path, but that path does not exist on disk (`Path::exists()` follows symlinks, so a dangling symlink also triggers this). The check runs before any target handling, so nothing is created for an absent source.

Solutions

  1. Inspect the staged directory and correct the `source` string to the real file name
  2. Use the installer's template variables for version-stamped names so the path stays valid across releases
  3. Re-stage the payload (remove the caskroom staging dir, reinstall) to rule out partial extraction
  4. If the file is optional, guard the step with `if_exists` on the source

Example fix

# before
copy(source: "bin/mytool-v1.2", target: "#{staged}/bin/mytool")
# after
copy(source: "bin/mytool-#{version}", target: "#{staged}/bin/mytool")
Defensive patterns

Strategy: validation

Validate before calling

// Verify the resolved copy source exists before executing the step
let source = resolve_flight_path_with_context(cask, &step.source, staged_path, appdir)?;
if !source.exists() {
    return Err(eyre!("copy source '{}' missing in staged payload; re-stage the cask", source.display()));
}

Try / catch

if err.to_string().contains("copy source") && err.to_string().contains("was not found") {
    // trigger a re-download/re-stage and retry once before surfacing to the user
}

Prevention

When it happens

Trigger: A non-glob `copy` whose source string names a file missing from the staged payload; a source that is a dangling symlink; template expansion producing a different name than what was staged.

Common situations: Upstream renamed the file between cask versions; partial or failed extraction of the staged archive; case-sensitive filesystem versus an archive built on macOS; typo in the source path.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/3b34788292462e8d. Report an issue: GitHub.

Appendix: source

Thrown at src/system/packages/brew/cask.rs:3566

            overwrite,
            source_glob,
            guards,
        } => {
            if !guards
                .iter()
                .map(|guard| flight_guard_matches(cask, guard, staged_path, appdir))
                .collect::<Result<Vec<_>>>()?
                .into_iter()
                .all(|matches| matches)
            {
                return Ok(());
            }
            let sources = flight_symlink_sources(cask, source, *source_glob, staged_path, appdir)?;
            let [source] = sources.as_slice() else {
                bail!("brew-cask: structured copy source must resolve to exactly one path");
            };
            if !source.exists() {
                bail!(
                    "brew-cask: structured copy source '{}' was not found",
                    source.display()
                );
            }
            if source.is_dir() && !recursive {
                bail!("brew-cask: structured directory copy requires recursive=true");
            }
            let target = resolve_flight_path_with_context(cask, target, staged_path, appdir)?;
            let external = !target.starts_with(staged_path);
            let target_metadata = target.symlink_metadata().ok();
            if target_metadata.is_some() {
                if !overwrite {
                    bail!(
                        "brew-cask: structured copy target '{}' already exists",
                        target.display()
                    );
                }
                if external {

View on GitHub (pinned to 6f52dcdf99)