{"record":{"id":"3d48f0f4012af85a","repo":"gitbutlerapp/gitbutler","slug":"field-is-required-when-provided","errorCode":null,"errorMessage":"{field} is required when provided","messagePattern":"(.+?) is required when provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-llm/src/config.rs","lineNumber":388,"sourceCode":"    }\n    Ok(())\n}\n\nfn set_provider(config: &mut gix::config::File, provider: LLMProviderKind) -> Result<()> {\n    set_config_value(\n        config,\n        AI_MODEL_PROVIDER_KEY,\n        provider.as_git_config_value(),\n    )\n}\n\nfn nonempty(value: Option<&str>) -> Option<&str> {\n    value.map(str::trim).filter(|value| !value.is_empty())\n}\n\nfn validate_optional(value: Option<&str>, field: &str) -> Result<()> {\n    if value.is_some() && nonempty(value).is_none() {\n        bail!(\"{field} is required when provided\")\n    }\n    Ok(())\n}\n\nfn config_value(config: &gix::config::File, key: &str) -> Option<String> {\n    config.string(key).map(|value| value.to_string())\n}\n\nfn required<'a>(value: &'a str, field: &str) -> Result<&'a str> {\n    let value = value.trim();\n    if value.is_empty() {\n        bail!(\"{field} is required\")\n    }\n    Ok(value)\n}\n\nfn validate_url(value: &str, field: &str) -> Result<()> {\n    let value = required(value, field)?;","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-llm/src/config.rs#L370-L406","documentation":"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.","triggerScenarios":"Applying OpenAI/Anthropic/Ollama/LMStudio/OpenRouter configuration via git config where a key exists but its value is an empty string or only whitespace.","commonSituations":"Setting an API key to \"\" to 'clear' it, leftover empty entries in .git/config, or scripting that writes `git config key ''`.","solutions":["Provide a non-empty value for the field","Remove the config key entirely instead of setting it to an empty string","Trim user input before writing it to config"],"exampleFix":"// before\ngit config but-llm.openai.api-key ''\n// after\ngit config --unset but-llm.openai.api-key\ngit config but-llm.openai.api-key 'sk-...'","handlingStrategy":"validation","validationCode":"// Rust\nfn is_blank(s: Option<&str>) -> bool { s.map(str::trim).exists(|t| t.is_empty()) }\n// TS\nconst isValid = (v?: string) => v != null && v.trim().length > 0;","typeGuard":"const isNonEmptyString = (v: unknown): v is string =>\n  typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Use `git config --unset` rather than writing empty strings","Trim values before persisting to config","Validate config at startup and surface which field is blank"],"tags":["config","validation","empty-value"],"backgroundTag":"empty-required-field","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}