gitbutlerapp/gitbutler · error

is required when provided

Error message

{field} is required when provided

What it means

Raised by validate_optional when a config field was provided (Some) but is empty or whitespace-only after trimming. The library refuses to accept a present-but-blank value for fields like API keys or endpoints.

Solutions

  1. Provide a non-empty value for the field
  2. Remove the config key entirely instead of setting it to an empty string
  3. Trim user input before writing it to config

Example fix

// before
git config but-llm.openai.api-key ''
// after
git config --unset but-llm.openai.api-key
git config but-llm.openai.api-key 'sk-...'
Defensive patterns

Strategy: validation

Validate before calling

// Rust
fn is_blank(s: Option<&str>) -> bool { s.map(str::trim).exists(|t| t.is_empty()) }
// TS
const isValid = (v?: string) => v != null && v.trim().length > 0;

Type guard

const isNonEmptyString = (v: unknown): v is string =>
  typeof v === 'string' && v.trim().length > 0;

Prevention

When it happens

Trigger: Applying OpenAI/Anthropic/Ollama/LMStudio/OpenRouter configuration via git config where a key exists but its value is an empty string or only whitespace.

Common situations: Setting an API key to "" to 'clear' it, leftover empty entries in .git/config, or scripting that writes `git config key ''`.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at crates/but-llm/src/config.rs:388

    }
    Ok(())
}

fn set_provider(config: &mut gix::config::File, provider: LLMProviderKind) -> Result<()> {
    set_config_value(
        config,
        AI_MODEL_PROVIDER_KEY,
        provider.as_git_config_value(),
    )
}

fn nonempty(value: Option<&str>) -> Option<&str> {
    value.map(str::trim).filter(|value| !value.is_empty())
}

fn validate_optional(value: Option<&str>, field: &str) -> Result<()> {
    if value.is_some() && nonempty(value).is_none() {
        bail!("{field} is required when provided")
    }
    Ok(())
}

fn config_value(config: &gix::config::File, key: &str) -> Option<String> {
    config.string(key).map(|value| value.to_string())
}

fn required<'a>(value: &'a str, field: &str) -> Result<&'a str> {
    let value = value.trim();
    if value.is_empty() {
        bail!("{field} is required")
    }
    Ok(value)
}

fn validate_url(value: &str, field: &str) -> Result<()> {
    let value = required(value, field)?;

View on GitHub (pinned to 58e5313667)