gitbutlerapp/gitbutler · error

with --key-option bring-your-own requires --api-key or…

Error message

{provider} with --key-option bring-your-own requires --api-key or --api-key-env

What it means

When the AI key option is `bring-your-own` (BYOK), the CLI must obtain the secret non-interactively via --api-key or --api-key-env. `require_non_interactive_secret_if_byok` bails if BYOK was selected but no secret was resolved, interpolating the provider name into the message.

Solutions

  1. Add --api-key-env MY_PROVIDER_KEY to the command (preferred for scripts)
  2. Or add --api-key <value> if inline keys are acceptable
  3. Switch --key-option to a hosted/built-in option if the provider should use GitButler-managed keys instead

Example fix

// before
but config ai --provider myproxy --key-option bring-your-own
// after
but config ai --provider myproxy --key-option bring-your-own --api-key-env MYPROXY_API_KEY
Defensive patterns

Strategy: validation

Validate before calling

function assertByokSecret({ keyOption, apiKey, apiKeyEnv, provider }) {
  if (keyOption === 'bring-your-own' && !apiKey && !apiKeyEnv) {
    throw new Error(`${provider} bring-your-own requires --api-key or --api-key-env`);
  }
}

Type guard

const isByokMissingSecret = (o) => o.keyOption === 'bring-your-own' && !o.apiKey && !o.apiKeyEnv;

Try / catch

try {
  await configureAi(args);
} catch (e) {
  if (/requires --api-key or --api-key-env/.test(e.message)) {
    console.error('Supply the provider key via --api-key-env PROVIDER_KEY');
  } else throw e;
}

Prevention

When it happens

Trigger: Running `but config ai --provider <p> --key-option bring-your-own` without either --api-key or --api-key-env in a non-interactive context (ai_config_non_interactive path).

Common situations: Scripts configuring a custom provider endpoint but forgetting to pass the key; users assuming BYOK means 'no key needed'; automation where interactive prompting is unavailable so the secret must be supplied explicitly.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/2920b1fed64c7027. Report an issue: GitHub.

Appendix: source

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

        return Ok(Some(Sensitive(value)));
    }

    if let Some(env_name) = api_key_env {
        let value = std::env::var(&env_name)
            .with_context(|| format!("Environment variable '{env_name}' is not set"))?;
        return Ok(Some(Sensitive(value)));
    }

    Ok(None)
}

fn require_non_interactive_secret_if_byok(
    key_option: AiKeyOption,
    secret: Option<&Sensitive<String>>,
    provider: &str,
) -> Result<()> {
    if matches!(key_option, AiKeyOption::BringYourOwn) && secret.is_none() {
        anyhow::bail!(
            "{provider} with --key-option bring-your-own requires --api-key or --api-key-env"
        );
    }
    Ok(())
}

fn maybe_set_secret(handle: &str, secret_value: Option<Sensitive<String>>) -> Result<()> {
    if let Some(secret_value) = secret_value {
        secret::persist(handle, &secret_value, secret::Namespace::Global)?;
    }
    Ok(())
}

fn edit_ai_git_config(
    repo: Option<&gix::Repository>,
    scope: AiScope,
    edit: impl FnOnce(&mut gix::config::File) -> Result<()>,
) -> Result<()> {

View on GitHub (pinned to 58e5313667)