gitbutlerapp/gitbutler · error · anyhow::Error

Enter an OpenAI API key

Error message

Enter an OpenAI API key

What it means

Validation in the AI configuration update flow: when the active provider is OpenAI with the 'BringYourOwn' credential option, a usable key must exist — either submitted in this update or already stored for the project. If both are absent, `validate_update` rejects the update with this form-style message.

Source

Thrown at crates/but-napi/src/ai.rs:136

    value.and_then(|value| {
        let value = value.trim();
        (!value.is_empty()).then(|| value.to_string())
    })
}

fn validate_update(
    update: &AiConfigurationUpdate,
    openai_has_key: bool,
    anthropic_has_key: bool,
) -> Result<()> {
    let configuration = domain_configuration(update, DomainConfiguration::default())?;

    if configuration.provider == LLMProviderKind::OpenAi
        && configuration.openai.key_option == CredentialsKeyOption::BringYourOwn
        && submitted_key(update.openai_api_key.clone()).is_none()
        && !openai_has_key
    {
        bail!("Enter an OpenAI API key")
    }
    if configuration.provider == LLMProviderKind::Anthropic
        && configuration.anthropic.key_option == CredentialsKeyOption::BringYourOwn
        && submitted_key(update.anthropic_api_key.clone()).is_none()
        && !anthropic_has_key
    {
        bail!("Enter an Anthropic API key")
    }
    Ok(())
}

fn domain_configuration(
    update: &AiConfigurationUpdate,
    mut configuration: DomainConfiguration,
) -> Result<DomainConfiguration> {
    configuration.provider = provider(&update.provider)?;
    configuration.openai = OpenAiConfiguration {
        key_option: key_option("OpenAI", &update.openai_key_option)?,

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Include a non-empty (after trim) `openai_api_key` in the same update
  2. If a key is already stored, make sure the update does not clear it and resend the stored-key state
  3. Switch the credential option away from bring-your-own if no key should be supplied

Example fix

// before
await updateAiConfig({ provider: 'openai', openaiKeyOption: 'bring-your-own' }); // bails

// after: submit the key together with the option
await updateAiConfig({
  provider: 'openai',
  openaiKeyOption: 'bring-your-own',
  openaiApiKey: keyInput.trim(), // must be non-empty
});
Defensive patterns

Strategy: validation

Validate before calling

// TypeScript: pre-validate the BYO key requirement client-side
if (
  update.provider === 'openai' &&
  update.openaiKeyOption === 'bring-your-own' &&
  !(update.openaiApiKey ?? '').trim() &&
  !hasStoredOpenAiKey
) {
  showFieldError('openaiApiKey', 'Enter an OpenAI API key');
  return;
}
await updateAiConfig(update);

Try / catch

Catch the NAPI error whose message is 'Enter an OpenAI API key' and attach it to the key input field; keep the user on the form instead of failing silently.

Prevention

When it happens

Trigger: An `AiConfigurationUpdate` with provider=openai and openai_key_option=bring-your-own, no non-empty `openai_api_key` in the payload (after trim), and no previously stored OpenAI key.

Common situations: First-time setup where the user selects bring-your-own but leaves the key field empty; the frontend submits the update before the key input state is populated; a previously stored key was cleared.

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@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/08a619eda4474e53. Report an issue: GitHub.