jdx/mise · error
brew-cask:{}: Homebrew took ownership of this cask while ins
Error message
brew-cask:{}: Homebrew took ownership of this cask while installation was pending What it means
mise re-checks Homebrew ownership at the last moment: after downloading and staging the cask payload (under the caskroom lock), it looks again for the `.metadata` marker. If it appeared since the first check, a concurrent `brew install --cask` claimed the cask mid-flight; mise deletes its staged payload and aborts rather than clobber brew's install — a TOCTOU guard.
Source
Thrown at src/system/packages/brew/cask.rs:466
for completion in &artifacts.completions {
miseprintln!(
"install {} completion {}",
completion.shell.name(),
completion.source
);
}
for generated in &artifacts.generated_completions {
miseprintln!("generate completions from {}", generated.executable);
}
return Ok(cask.version);
}
prefix::bootstrap(false)?;
let stage = fetch_and_stage(&cask, pr).await?;
let _caskroom_lock = lock_caskroom()?;
recover_flight_backups()?;
if homebrew_metadata_present(&cask.token) {
file::remove_all(&stage)?;
bail!(
"brew-cask:{}: Homebrew took ownership of this cask while installation was pending",
cask.token
);
}
if installed_cask_version(&cask, &artifacts)?.as_deref() == Some(cask.version.as_str()) {
file::remove_all(stage)?;
return Ok(cask.version);
}
let previous_binaries = previous_binary_targets(&cask)?;
let previous_fonts = previous_font_targets(&cask)?;
let previous_completions = previous_completion_targets(&cask)?;
let previous_flight_symlinks = previous_flight_symlink_targets(&cask)?;
let previous_flight_directories = previous_flight_directory_targets(&cask)?;
let previous_generic = previous_generic_targets(&cask)?;
let caskroom_token = caskroom_token_dir(&cask.token);
let caskroom = caskroom_version_dir(&cask.token, &cask.version);
let tmp_caskroom = caskroom_tmp_dir(&cask);
file::remove_all(&tmp_caskroom)?;View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Let the other installation finish, verify with `brew list --cask`, then re-run the mise command — mise will detect the cask as installed
- Serialize installs: never run brew and mise cask installs concurrently for the same token
Defensive patterns
Strategy: retry
Validate before calling
// Right before retrying, confirm whether the concurrent brew install finished:
fn cask_installed_by_homebrew(token: &str) -> bool {
std::path::Path::new(&caskroom(token)).join(".metadata").symlink_metadata().is_ok()
} Try / catch
Catch the 'took ownership while installation was pending' bail, wait for any concurrent brew process to exit, then re-run the mise install — the idempotent path will then report already-installed or proceed cleanly.
Prevention
- Don't run brew install --cask and mise bootstrap concurrently for the same token
- In CI, sequence GUI-app installs instead of parallelizing them
When it happens
Trigger: Running mise install/bootstrap for a cask while another process (brew CLI, another mise invocation, a CI step) installs the same cask; the marker appears between mise's pre-check and the post-staging re-check.
Common situations: Bootstrap scripts racing brew one-liners in dotfiles; parallel CI steps installing the same GUI tool; two mise processes started concurrently.
Related errors
- brew-cask: refusing elevated operation because target appear
- brew-cask:{}: dependency cycle detected
- brew-cask:{}: Homebrew owns this cask; remove it with Homebr
- brew-cask:{}: conflicts with installed cask {}
- brew casks are installed at their current version ('{p}')
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/5a928da20b6f0530.
Report an issue: GitHub.