{"record":{"id":"7c6d9938135fa303","repo":"jdx/mise","slug":"brew-cask-structured-symlink-globs-must-use-stage-7c6d99","errorCode":null,"errorMessage":"brew-cask: structured symlink globs must use staged_path","messagePattern":"brew-cask: structured symlink globs must use staged_path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/flight.rs","lineNumber":945,"sourceCode":"        FlightGuard::IfExists(path) => {\n            Ok(resolve_flight_path_with_context(cask, path, staged_path, appdir)?.exists())\n        }\n        FlightGuard::UnlessExists(path) => {\n            Ok(!resolve_flight_path_with_context(cask, path, staged_path, appdir)?.exists())\n        }\n    }\n}\n\npub(super) fn flight_symlink_sources(\n    cask: &Cask,\n    source: &FlightPath,\n    source_glob: bool,\n    staged_path: &Path,\n    appdir: &Path,\n) -> Result<Vec<PathBuf>> {\n    if source_glob {\n        if source.base != FlightPathBase::StagedPath {\n            bail!(\"brew-cask: structured symlink globs must use staged_path\");\n        }\n        let pattern = expand_flight_template(cask, &source.path, staged_path, appdir);\n        return expand_staged_glob(staged_path, &pattern);\n    }\n    Ok(vec![resolve_flight_path_with_context(\n        cask,\n        source,\n        staged_path,\n        appdir,\n    )?])\n}\n\npub(super) fn create_flight_symlink(source: &Path, target: &Path, sudo: FlightSudo) -> Result<()> {\n    match sudo {\n        FlightSudo::Never => file::make_symlink(source, target).map(|_| ()),\n        FlightSudo::IfNeeded => make_symlink_elevating(source, target),\n        FlightSudo::Always => sudo::run(\"/bin/ln\", &symlink_command_args(source, target), &[]),\n    }","sourceCodeStart":927,"sourceCodeEnd":963,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/brew/cask/flight.rs#L927-L963","documentation":"Brew-cask structured symlink steps that use glob sources must anchor them at the staged application path (FlightPathBase::StagedPath). A glob with a different base (e.g. appdir or an absolute base) is rejected, since the library only expands and constrains globs within the staged bundle.","triggerScenarios":"FlightStep::Copy or FlightStep::Symlink with source_glob=true whose source.base is not StagedPath — e.g. a cask definition specifying a glob relative to appdir or an absolute path instead of the staged bundle.","commonSituations":"Cask authors writing globs intended to match already-installed files in the appdir rather than staged contents; copy-pasting a non-glob source (which may use other bases) into a glob-based step; misunderstanding that globs are staged_path-relative by design.","solutions":["Change the source's base to staged_path in the flight step definition.","If the file lives outside the staged bundle, drop source_glob and use a non-glob source path with the appropriate base.","Restructure the step so the glob matches files inside the staged bundle and a separate step links/copies outward."],"exampleFix":"// before\nsource: { base: \"appdir\", path: \"plugins/*.bundle\", glob: true }\n// after\nsource: { base: \"staged_path\", path: \"MyApp.app/Contents/PlugIns/*.bundle\", glob: true }","handlingStrategy":"validation","validationCode":"if source_glob && source.base != FlightPathBase::StagedPath {\n    return Err(eyre!(\"globs must be declared with base staged_path\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare glob sources with base=staged_path and staged-relative paths.","Use non-glob sources for anything outside the staged bundle.","Validate cask flight definitions against the schema before publishing."],"tags":["brew-cask","glob","validation","configuration"],"backgroundTag":"invalid-argument-value","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}