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

  1. Restore the appdir configuration the cask was installed with so the app's location is an allowed root again
  2. Move the app bundle back under an allowed Applications directory and ensure Caskroom/<token>/<version>/<name>.app still matches it
  3. Reinstall the cask (regenerates both staged copy and receipt), then prune
  4. 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

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


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/6a0babd9253e108d. Report an issue: GitHub.