jdx/mise · error
brew-cask: structured directory copy requires recursive=true
Error message
brew-cask: structured directory copy requires recursive=true
What it means
A brew-cask structured copy step resolved its source to a directory, but the step was declared with recursive=false. The library refuses a shallow/ambiguous directory copy and requires the caller to opt in to recursive copying explicitly.
Source
Thrown at src/system/packages/brew/cask/flight.rs:660
overwrite,
source_glob,
guards,
} => {
if !flight_guards_pass(cask, guards, staged_path, appdir)? {
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 {
targets.protect(&target)?;
} else {
file::remove_all(&target)?;
}
}
if let Some(parent) = target.parent() {View on GitHub (pinned to afd2eddd3a)
Solutions
- Set recursive: true on the Copy flight step.
- If only a single file is wanted, narrow the source path/glob to the specific file.
- Reconsider using a Symlink step instead of copying a large directory.
Example fix
// before
FlightStep::Copy { source: "MyApp.app", recursive: false, .. }
// after
FlightStep::Copy { source: "MyApp.app", recursive: true, .. } Defensive patterns
Strategy: validation
Validate before calling
if source.is_dir() && !recursive {
return Err(eyre!("set recursive=true to copy directory {}", source.display()));
} Prevention
- Default to recursive=true when copying .app bundles or plugin directories.
- Check whether the resolved source is a file or directory before choosing recursive.
When it happens
Trigger: FlightStep::Copy { source: <dir>, recursive: false } where source resolves to a directory inside staged_path — typically a glob matching a bundle/directory, or a literal path that became a directory after an upstream change.
Common situations: Cask authors copying a .app bundle or plugin directory but forgetting recursive=true; a glob that used to match a file now matches a directory after a version bump.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- brew-cask: structured symlink globs must use staged_path
- brew casks are installed at their current version ('{p}')
- brew-cask: requested token '{requested_token}' does not matc
- brew-cask: invalid {kind} '{value}'
- brew-cask: structured file operation must use staged_path
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/837fd4c1bb44c3db.
Report an issue: GitHub.