jdx/mise · error · eyre::Report
app target is outside an allowed Applications directory: {}
Error message
app target is outside an allowed Applications directory: {} What it means
App-bundle targets must be directories located below one of the allowed Applications roots (default /Applications plus any configured appdir), and the staged copy inside the Caskroom version directory must fingerprint-match the installed bundle. This guard stops the prune from deleting .app bundles that were moved, replaced, or installed somewhere the tool never sanctioned.
Source
Thrown at src/system/packages/brew/cask.rs:7050
bail!("receipt target inventory is incomplete or duplicated");
}
if records.keys().any(|path| !expected.contains(path)) {
bail!("receipt target inventory contains an unclassified path");
}
for path in &receipt.apps {
let record = records
.get(path)
.ok_or_else(|| eyre!("missing app target record"))?;
if record.fingerprint.kind != CaskTargetKind::Directory
|| !allowed_appdir_roots()?
.iter()
.any(|root| path_is_below(path, root))
|| !path.file_name().is_some_and(|name| {
staged_app_matches_target(record, &candidate.version_dir.join(name))
})
{
bail!(
"app target is outside an allowed Applications directory: {}",
path.display()
);
}
}
for path in &receipt.binaries {
let record = records
.get(path)
.ok_or_else(|| eyre!("missing binary target record"))?;
if record.fingerprint.kind != CaskTargetKind::Symlink
|| !allowed_binary_target_roots()
.iter()
.any(|root| path_is_below(path, root))
|| !symlink_resolves_below(path, &candidate.version_dir)
{
bail!(
"binary target is not an owned Caskroom symlink: {}",
path.display()View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Restore the appdir configuration the cask was installed with so the app's location is an allowed root again
- Move the app bundle back under an allowed Applications directory and ensure Caskroom/<token>/<version>/<name>.app still matches it
- Reinstall the cask (regenerates both staged copy and receipt), then prune
- If the app is intentionally elsewhere, uninstall the cask explicitly instead of pruning
Example fix
# before: app installed to ~/Applications via appdir, setting later removed # receipt.apps = ["/Users/me/Applications/Thing.app"] -> not below allowed roots # after: re-add the appdir before pruning brew.appdir = '~/Applications' # restore in config mise system prune
Defensive patterns
Strategy: validation
Validate before calling
// Before pruning, confirm each app sits below an allowed root and the staged
// copy matches (the same predicate the validator uses).
fn app_ok(candidate: &CaskPruneCandidate, path: &Path) -> Result<bool> {
let Some(name) = path.file_name() else { return Ok(false) };
Ok(allowed_appdir_roots()?.iter().any(|root| path_is_below(path, root))
&& staged_app_matches_target(
&records[candidate].find(path).unwrap(),
&candidate.version_dir.join(name),
))
} Type guard
fn app_path_allowed(path: &Path, roots: &[PathBuf]) -> bool {
roots.iter().any(|root| path.strip_prefix(root).is_ok_and(|rel| rel.components().next().is_some()))
} Try / catch
// Per-cask skip; never abort the prune run because one app bundle moved.
if let Err(reason) = validate_cask_prune_candidate(candidate) {
warn!("brew-cask:{}: skipped: {reason:#}", candidate.token);
continue;
} Prevention
- Keep the appdir setting stable across install and prune
- Leave .app bundles where the cask installed them; relocate via reinstall, not drag-and-drop
- Do not delete staged copies inside Caskroom/<token>/<version>/
When it happens
Trigger: validate_cask_prune_candidate, apps loop: record.fingerprint.kind != Directory, path not below any allowed_appdir_roots() entry, or staged_app_matches_target fails against version_dir/<app-name>. Typical causes: the appdir setting changed after install, the user dragged the app out of /Applications, or the staged copy in Caskroom was deleted.
Common situations: Installing with a custom appdir (e.g. ~/Applications) and later removing that setting; user moved the app to another folder; app updated itself in place; staged Caskroom copy removed to save space.
Related errors
- font target is outside the platform font directory: {}
- ownership receipt has changed
- receipt is not marked safe for direct-artifact pruning
- receipt target inventory is incomplete or duplicated
- receipt target inventory contains an unclassified path
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/6a0babd9253e108d.
Report an issue: GitHub.