BoundaryML/baml · error

are mutually exclusive dispatch modes — pick one.

Error message

{} are mutually exclusive dispatch modes — pick one.

What it means

`baml run` supports several mutually exclusive dispatch modes (e.g. `--function`-style script body, expression evaluation, standalone file); more than one was supplied on the command line, so the CLI refuses to guess which to use.

Solutions

  1. Keep only one dispatch mode flag in the command
  2. Run separate invocations for each mode you need
  3. Check your script/alias for accumulated duplicate flags

Example fix

// before
baml run --file script.py --expr 'MyFunc(1)'
// after
baml run --expr 'MyFunc(1)'
Defensive patterns

Strategy: validation

Validate before calling

function countDispatchModes(flags) {
  const modes = ['expr', 'file', 'script', 'project'].filter(m => flags[m] !== undefined);
  if (modes.length > 1) throw new Error('mutually exclusive: ' + modes.join(', '));
}

Try / catch

try { await baml.run(args); } catch (e) { if (String(e).includes('mutually exclusive dispatch modes')) { console.error('Pick exactly one dispatch mode'); } else throw e; }

Prevention

When it happens

Trigger: `run_with_reporter` collects which dispatch-mode flags were given and finds more than one set, e.g. passing both an expression and a standalone file mode.

Common situations: Combining `--expr` with `--file`, or a script body with another mode in one `baml run` invocation; alias scripts that accumulate flags.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/8195f7e68fccd475. Report an issue: GitHub.

Appendix: source

Thrown at baml_language/crates/baml_cli/src/run_command.rs:402

        crate::reporter::print_verbose(format_args!("profiling: {status}"));
    }
}

impl RunArgs {
    fn run_with_reporter(&self, reporter: &Reporter) -> Result<crate::ExitCode> {
        // Dispatch modes are mutually exclusive. Positional target /
        // `-f` (one or many) / `-e` all replace each other.
        let dispatch_modes: &[(&str, bool)] = &[
            ("`<target>`", self.target.is_some()),
            ("`-f`", !self.functions.is_empty()),
            ("`-e`", self.expression.is_some()),
        ];
        let used: Vec<&str> = dispatch_modes
            .iter()
            .filter_map(|(name, given)| given.then_some(*name))
            .collect();
        if used.len() > 1 {
            anyhow::bail!(
                "{} are mutually exclusive dispatch modes — pick one.",
                used.join(" and ")
            );
        }

        // `--file` is the standalone-source alternative to `--project`. Both
        // pointing at sources would be ambiguous (which one wins?), so
        // reject an explicit combination up front.
        validate_file_project_flags(self.file.as_deref(), self.from.as_deref())?;

        // Expression mode short-circuits before reaching project / file
        // loading, so combining `-e` with surfaces that change *what* is
        // loaded silently does nothing. Reject up front to avoid the
        // footgun.
        if self.expression.is_some() {
            if self.file.is_some() {
                anyhow::bail!(
                    "`-e` is not compatible with `--file`. Expression mode \

View on GitHub (pinned to bd85ce9dee)