gitbutlerapp/gitbutler · error
Enter an Anthropic API key
Error message
Enter an Anthropic API key
What it means
Validation error from `validate_update` (called by `update_ai_configuration`): an Anthropic provider configuration using the BringYourOwn credential option requires an API key, but none was submitted and none exists in storage. Prevents saving an Anthropic configuration that could not authenticate.
Solutions
- Provide a non-empty `anthropic_api_key` in the update request
- Keep the stored key (an existing key satisfies the check) instead of clearing it
- Switch `anthropic.key_option` to a non-BringYourOwn credential source
- Ensure the submitted key is not blank/whitespace
Example fix
// before
await api.updateAiConfiguration({ provider: "Anthropic", anthropic: { keyOption: "BringYourOwn" } });
// after
await api.updateAiConfiguration({
provider: "Anthropic",
anthropic: { keyOption: "BringYourOwn" },
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
}); Defensive patterns
Strategy: validation
Validate before calling
if (cfg.provider === "anthropic" && cfg.anthropic.keyOption === "BringYourOwn" &&
!update.anthropicApiKey?.trim() && !(await api.hasStoredAnthropicKey())) {
throw new Error("anthropic api key required before saving");
} Type guard
function hasAnthropicKey(u: AiConfigUpdate): boolean {
return typeof u.anthropicApiKey === "string" && u.anthropicApiKey.trim().length > 0;
} Try / catch
try {
await api.updateAiConfiguration(update);
} catch (e) {
if (String(e).includes("Enter an Anthropic API key")) {
setFieldError("anthropicApiKey", "required for BringYourOwn credential mode");
} else { throw e; }
} Prevention
- Require the Anthropic key field when BringYourOwn is selected and no key is stored
- Gate the save button on key presence in the settings UI
- Keep the stored key unless the user explicitly provides a replacement
- Trim inputs; whitespace-only keys are treated as absent
When it happens
Trigger: Calling the AI configuration update with provider=anthropic, anthropic.key_option=BringYourOwn, empty/absent `anthropic_api_key` in the update payload, and no previously stored Anthropic key.
Common situations: Switching provider to Anthropic without entering a key; clearing the key field and saving; wiping the credential store then attempting to update settings.
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
- Enter an Anthropic API key
- Enter an OpenAI API key
- When using Anthropic in a bring your own key configuration…
- Enter an OpenAI API key
- Environment variable ANTHROPIC_API_KEY is not set
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/a397ce8cb57f1255.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-api/src/ai.rs:188
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)?,
model: update.openai_model.clone(),
custom_endpoint: update.openai_custom_endpoint.clone(),
};
configuration.anthropic = AnthropicConfiguration {
key_option: key_option("Anthropic", &update.anthropic_key_option)?,
model: update.anthropic_model.clone(),
};View on GitHub (pinned to 58e5313667)