{"record":{"id":"aba5a30e4a04a0d7","repo":"jdx/mise","slug":"brew-cask-internal-non-terminate-flight-step","errorCode":null,"errorMessage":"brew-cask: internal non-terminate flight step","messagePattern":"brew-cask: internal non-terminate flight step","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/flight.rs","lineNumber":873,"sourceCode":"pub(super) fn execute_terminate_process(\n    step: &FlightStep,\n    staged_path: &Path,\n    appdir: &Path,\n    version: &str,\n    mut run: impl FnMut(&Path, &[String], bool) -> Result<()>,\n    mut sleep: impl FnMut(std::time::Duration),\n) -> Result<()> {\n    let FlightStep::TerminateProcess {\n        name,\n        match_mode,\n        sudo,\n        attempts,\n        must_succeed,\n        notices,\n        failure_message,\n    } = step\n    else {\n        bail!(\"brew-cask: internal non-terminate flight step\");\n    };\n    let expand = |value: &str| expand_cask_template(value, staged_path, appdir, Some(version));\n    for notice in notices {\n        miseprintln!(\"{}\", expand(notice));\n    }\n    let name = expand(name);\n    let (command, args) = match *match_mode {\n        ProcessMatch::Name => (Path::new(\"/usr/bin/killall\"), vec![name]),\n        ProcessMatch::Full => (Path::new(\"/usr/bin/pkill\"), vec![\"-f\".to_string(), name]),\n    };\n    let mut last_error = None;\n    for attempt in 0..*attempts {\n        match run(command, &args, *sudo) {\n            Ok(()) => return Ok(()),\n            Err(err) => last_error = Some(err),\n        }\n        if attempt + 1 < *attempts {\n            sleep(std::time::Duration::from_secs(1));","sourceCodeStart":855,"sourceCodeEnd":891,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/brew/cask/flight.rs#L855-L891","documentation":"Internal invariant violation: execute_terminate_process was invoked with a FlightStep that is not FlightStep::TerminateProcess. This function destructures the step to read the terminate-process parameters; any other variant means a caller bug in dispatching flight steps.","triggerScenarios":"A code path (or test) calls execute_terminate_process with a Move/Copy/Symlink/Run/Remove step instead of routing it through execute_flight_step's match. Not reachable through normal cask execution.","commonSituations":"Development-time mistake when adding a new FlightStep variant or refactoring step dispatch; tests constructing steps manually and passing the wrong variant to execute_terminate_process.","solutions":["Route all flight steps through execute_flight_step, which dispatches on the variant.","Fix the caller to match only FlightStep::TerminateProcess before calling execute_terminate_process.","If a new FlightStep variant was added, extend the match in execute_flight_step instead of reusing execute_terminate_process."],"exampleFix":"// before\nexecute_terminate_process(&step, ...); // step may be any variant\n// after\nif let FlightStep::TerminateProcess { .. } = &step {\n    execute_terminate_process(&step, ...);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn as_terminate(step: &FlightStep) -> Option<&FlightStep> {\n    match step {\n        FlightStep::TerminateProcess { .. } => Some(step),\n        _ => None,\n    }\n}","tryCatchPattern":null,"preventionTips":["Always dispatch flight steps via execute_flight_step's match.","Let the compiler's exhaustiveness checks cover new FlightStep variants.","Construct TerminateProcess steps only in tests that exercise execute_terminate_process."],"tags":["internal","invariant","brew-cask","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}