{"record":{"id":"2e47dddb532f173c","repo":"jdx/mise","slug":"brew-cask-app-target-target-name-must-be-unde-2e47dd","errorCode":null,"errorMessage":"brew-cask: app target '{target_name}' must be under {}","messagePattern":"brew-cask: app target '(.+?)' must be under (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/paths.rs","lineNumber":141,"sourceCode":"        {\n            bail!(\"brew-cask: app target '{target_name}' must not contain '..'\");\n        }\n        if path.is_absolute() {\n            let prefix_app_dir = prefix::prefix().join(\"Applications\");\n            if path.starts_with(&app_dir) || path.starts_with(&prefix_app_dir) {\n                return Ok(path);\n            }\n            // Casks routinely hardcode an absolute `/Applications/Foo.app`\n            // target. When an override appdir is configured, relocate such a\n            // target into it (preserving any subdirectories) rather than\n            // rejecting it. `$HOMEBREW_PREFIX`-anchored targets are handled by\n            // the check above and are never relocated.\n            if app_dir != Path::new(DEFAULT_APP_DIR)\n                && let Ok(rest) = path.strip_prefix(DEFAULT_APP_DIR)\n            {\n                return Ok(app_dir.join(rest));\n            }\n            bail!(\n                \"brew-cask: app target '{target_name}' must be under {}\",\n                app_dir.display()\n            );\n        }\n        bail!(\"brew-cask: app target '{target_name}' must be an absolute path\");\n    }\n    Ok(app_dir.join(target_name))\n}\n\n/// The directory `app` artifacts are linked into: `/Applications` unless\n/// [`APP_DIR_ENV`] overrides it.\n///\n/// The override is validated here rather than at the point of use because\n/// `app_target_path` treats the result as a containment boundary for symlinks\n/// that may be created with elevated privileges. An empty value falls back to\n/// the default so that exporting `MISE_BREW_CASK_OPT_APPDIR=` cannot disable\n/// that boundary: `Path::starts_with(\"\")` is true for every path.\npub(super) fn target_app_dir() -> Result<PathBuf> {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/cask/paths.rs#L123-L159","documentation":"For relative-sounding or absolute app targets that escaped the earlier checks, `app_target_path` requires the final path to live under the configured app directory. An absolute path not starting with the app dir or prefix Applications dir (and not relocatable from DEFAULT_APP_DIR) is rejected; a path that is not absolute at all is rejected with the sibling 'must be an absolute path' error.","triggerScenarios":"Passing an app target that is absolute but outside `$HOMEBREW_PREFIX/Applications`, the configured app_dir, or DEFAULT_APP_DIR (e.g. `/Users/me/Tools/Foo.app` or `/opt/Foo.app`) through any app install/adopt/validate call site.","commonSituations":"Pointing a cask app at a personal directory instead of the Homebrew Applications folder; switching the configured app_dir so previously valid targets now fall outside it; a cask definition hardcoding a non-standard absolute location.","solutions":["Change the app target to be under the configured app dir (default `/Applications` or `$HOMEBREW_PREFIX/Applications`).","Set the cask app dir configuration to include the intended parent directory, then re-run install.","Move the app into an allowed root and target it there if it must live elsewhere."],"exampleFix":"# before\napp target: \"/Users/alice/Tools/MyApp.app\"\n\n# after\napp target: \"$HOMEBREW_PREFIX/Applications/MyApp.app\"","handlingStrategy":"validation","validationCode":"let app_dir = target_app_dir()?;\nlet p = std::path::PathBuf::from(expand(target_name));\nif p.is_absolute() && !p.starts_with(&app_dir) {\n    return Err(format!(\"target must be under {}\", app_dir.display()));\n}","typeGuard":"fn under_app_dir(p: &std::path::Path, app_dir: &std::path::Path) -> bool {\n    p.is_absolute() && p.starts_with(app_dir)\n}","tryCatchPattern":null,"preventionTips":["Keep app targets under $HOMEBREW_PREFIX/Applications or /Applications.","If you change the configured app dir, update all cask app targets to match.","Reject absolute paths outside known roots at config-parse time rather than install time."],"tags":["brew-cask","path-validation","config","allowed-roots"],"backgroundTag":"invalid-config-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}