jdx/mise · error

brew-cask: structured file operation must use staged_path

Error message

brew-cask: structured file operation must use staged_path

What it means

Structured cask flight operations (move/symlink/etc.) must reference paths relative to the cask's `staged_path` base. Homebrew throws this when a FlightPath declares any other base (e.g. an absolute or home-relative base), which the structured API forbids by design.

Source

Thrown at src/system/packages/brew/cask/flight.rs:1055

                );
            }
            matches.push(path);
        }
    }
    matches.sort();
    matches.dedup();
    Ok(matches)
}

pub(super) fn is_flight_glob(path: &str) -> bool {
    path.chars()
        .any(|c| matches!(c, '*' | '?' | '[' | ']' | '{' | '}'))
}

pub(super) fn resolve_flight_path(staged_path: &Path, path: &FlightPath) -> Result<PathBuf> {
    match path.base {
        FlightPathBase::StagedPath => {}
        _ => bail!("brew-cask: structured file operation must use staged_path"),
    }
    let relative = Path::new(&path.path);
    validate_flight_relative_path(&path.path)?;
    Ok(staged_path.join(relative))
}

pub(super) fn resolve_flight_path_with_context(
    cask: &Cask,
    path: &FlightPath,
    staged_path: &Path,
    appdir: &Path,
) -> Result<PathBuf> {
    let expanded = expand_flight_template(cask, &path.path, staged_path, appdir);
    match path.base {
        FlightPathBase::StagedPath => {
            validate_flight_relative_path(&expanded)?;
            Ok(staged_path.join(expanded))
        }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Set the FlightPath base to StagedPath
  2. Express the target as a path relative to staged_path
  3. For operations outside staging, use the appropriate non-structured stanza or artifact DSL instead

Example fix

// before
FlightPath { base: FlightPathBase::Absolute, path: "/opt/tool/bin/x" }
// after
FlightPath { base: FlightPathBase::StagedPath, path: "bin/x" }
Defensive patterns

Strategy: type-guard

Validate before calling

if fp.base != FlightPathBase::StagedPath {
    return Err("structured flight op must use staged_path".into());
}

Type guard

fn is_staged_base(fp: &FlightPath) -> bool {
    matches!(fp.base, FlightPathBase::StagedPath)
}

Try / catch

match resolve_flight_path(staged, &fp) {
    Err(e) if e.to_string().contains("must use staged_path") => fix_base_and_retry(),
    r => r,
}

Prevention

When it happens

Trigger: A cask stanza passes a FlightPath whose `base` is not `FlightPathBase::StagedPath` — e.g. specifying an absolute path or another base variant in a structured move/symlink operation.

Common situations: Cask DSL authors porting old-style stanzas to the structured API and leaving an absolute path as base; internal tooling generating flight steps with the wrong base enum.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/b214b8e914294426. Report an issue: GitHub.