gitbutlerapp/gitbutler · error

Cannot pass both --local and --global

Error message

Cannot pass both --local and --global

What it means

AiScope::from_flags validates the --local and --global flags for `but config` AI settings. The two scopes are mutually exclusive: passing both makes the target config file ambiguous, so the command errors.

Solutions

  1. Pass only one of --local or --global.
  2. If neither is passed, the default (Global) scope is used — drop the redundant flag.
  3. Fix any script/alias that appends both flags.

Example fix

// before
but config set ai.model gpt-4 --local --global
// after
but config set ai.model gpt-4 --local
Defensive patterns

Strategy: validation

Validate before calling

const flags = [local, global].filter(Boolean).length;
if (flags > 1) throw new Error('Pass only one of --local or --global');

Try / catch

try {
  execSync(`but config set ai.model ${model} ${scopeFlag}`, { stdio: 'inherit' });
} catch (err) {
  if (String(err).includes('both --local and --global')) {
    execSync(`but config set ai.model ${model} --global`, { stdio: 'inherit' });
  } else { throw err; }
}

Prevention

When it happens

Trigger: Running `but config ... --local --global` (any AI config subcommand) with both boolean flags set to true.

Common situations: Copy-pasting CLI invocations and combining flag sets; scripts appending --global to an existing command that already had --local; misunderstanding that --global is a default rather than an override.

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 gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/f7123974a4e56f00. Report an issue: GitHub.

Appendix: source

Thrown at crates/but/src/command/config.rs:61

impl From<AiKeyOption> for String {
    fn from(value: AiKeyOption) -> Self {
        match value {
            AiKeyOption::BringYourOwn => "Bring your own key".to_string(),
            AiKeyOption::ButlerApi => "Use GitButler API".to_string(),
        }
    }
}

#[derive(Debug, Clone, Copy)]
enum AiScope {
    Global,
    Local,
}

impl AiScope {
    fn from_flags(local: bool, global: bool) -> Result<Self> {
        if local && global {
            anyhow::bail!("Cannot pass both --local and --global")
        }
        if local {
            Ok(AiScope::Local)
        } else {
            Ok(AiScope::Global)
        }
    }

    fn as_str(self) -> &'static str {
        match self {
            AiScope::Global => "global",
            AiScope::Local => "local",
        }
    }
}

type AiConfigInfo = AiConfigurationSnapshot;

View on GitHub (pinned to 58e5313667)