jdx/mise · error
brew-cask: refusing to stage generic artifact through a path
Error message
brew-cask: refusing to stage generic artifact through a path outside the caskroom: {} What it means
After resolving the artifact's relative position inside the stage, mise builds the corresponding path under the temporary caskroom and re-verifies containment with path_starts_with_resolved_root. If the constructed caskroom path resolves outside the temporary caskroom (e.g. a component of temporary_caskroom or the relative path is a symlink escaping it), staging is refused so the artifact can never be planted or linked through a location outside mise-controlled space.
Source
Thrown at src/system/packages/brew/cask/mod.rs:1574
"brew-cask: refusing generic artifact source outside the extraction root: {}",
source.display()
);
}
let target = generic_artifact_target_path(&artifact.target)?;
// Not a lexical `strip_prefix`: the lookup resolves symlinks it had to
// traverse, so a source reached that way can be contained by the stage
// without sharing its literal prefix — as it is whenever `stage` itself
// has a symlinked ancestor. `staged_relative_path` retries against the
// resolved stage, matching the containment check above.
let relative_source = staged_relative_path(stage, &source).ok_or_else(|| {
eyre!(
"brew-cask: generic artifact source is not contained by the extraction root: {}",
source.display()
)
})?;
let caskroom_source = temporary_caskroom.join(relative_source);
if !path_starts_with_resolved_root(&caskroom_source, temporary_caskroom) {
bail!(
"brew-cask: refusing to stage generic artifact through a path outside the caskroom: {}",
caskroom_source.display()
);
}
#[cfg(not(unix))]
if let Some(parent) = target.parent() {
file::create_dir_all(parent)?;
}
let elevated_target = targets.protect_generic(&target)?;
copy_generic_artifact(&source, &target, elevated_target.as_deref())?;
if let Some(parent) = caskroom_source.parent() {
file::create_dir_all(parent)?;
}
file::make_symlink(&target, &caskroom_source)?;
targets.record_installed(target);
Ok(())
}
View on GitHub (pinned to afd2eddd3a)
Solutions
- Check the temporary caskroom location for symlinked parents and use a plain directory path
- Re-run the install after removing any unexpected symlinks inside the caskroom
- Re-download/re-extract the cask to rule out a corrupted payload
- Report the issue to mise if your caskroom layout is conventional — this should not trigger on normal setups
Defensive patterns
Strategy: validation
Validate before calling
let caskroom_source = temporary_caskroom.join(&relative_source);
let resolved = dunce::canonicalize(temporary_caskroom)?.join(&relative_source);
if !resolved.starts_with(dunce::canonicalize(&temporary_caskroom)?) {
return Err(format!("staging path escapes caskroom: {}", caskroom_source.display()));
} Prevention
- Place the caskroom under a plain, non-symlinked directory (e.g. ~/.local/share/mise/cask)
- Do not create symlinks inside the caskroom that point elsewhere
- Keep consistent: install all casks as the same user
- If a layout triggers this unexpectedly, report it with the exact paths
When it happens
Trigger: install_generic_artifact computes caskroom_source = temporary_caskroom.join(relative_source), and path_starts_with_resolved_root determines that this joined path resolves outside the temporary caskroom — e.g. due to a symlinked directory at the join point or a relative_source containing traversal-like components that survive normalization.
Common situations: A caskroom parent directory containing symlinks; a compromised or unusual filesystem layout where the temporary caskroom path traverses a link; an artifact source path in the stage that, after staged_relative_path mapping, resolves through a symlink inside the caskroom.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- brew-cask: refusing generic artifact source outside the extr
- brew-cask: staged symlink path escaped extraction root: {}
- brew-cask: refusing generic artifact source outside the extr
- brew-cask: staged symlink path escaped extraction root: {}
- brew-cask: invalid {kind} '{value}'
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/5a626ed9f618262a.
Report an issue: GitHub.