{"record":{"id":"663e88e9d88bbaad","repo":"gitbutlerapp/gitbutler","slug":"field-is-required","errorCode":null,"errorMessage":"{field} is required","messagePattern":"(.+?) is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-llm/src/config.rs","lineNumber":400,"sourceCode":"fn 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)?;\n    let url = url::Url::parse(value).with_context(|| format!(\"{field} must be a valid URL\"))?;\n    if !matches!(url.scheme(), \"http\" | \"https\") || url.host_str().is_none() {\n        bail!(\"{field} must be an HTTP or HTTPS URL\")\n    }\n    Ok(())\n}\n\nfn validate_ollama_endpoint(value: &str) -> Result<()> {\n    let value = required(value, \"Ollama endpoint\")?;\n    if value.contains(\"://\") {\n        bail!(\"Ollama endpoint must use host:port format\")\n    }","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-llm/src/config.rs#L382-L418","documentation":"Raised by the required helper when a mandatory configuration value is missing or blank after trimming. Any of validate, validate_active, validate_url, or validate_ollama_endpoint can surface it, with {field} naming the offending config key.","triggerScenarios":"Running LLM configuration validation (validate/validate_active) or applying provider configuration while a required field such as an API key, model, or endpoint is unset or empty.","commonSituations":"Fresh checkout without provider setup, config section removed by hand, environment where the config file was never initialized.","solutions":["Set the named config field to a non-empty value","Run the provider setup flow (e.g. `but llm config`) to populate required keys","Check you are reading/writing the same config scope (global vs repo-local)"],"exampleFix":"// before: provider applied without key\napply_openai_configuration(None, ...)\n// after: supply required field\napply_openai_configuration(Some(\"sk-...\"), ...)","handlingStrategy":"validation","validationCode":"// TS\nfunction requireField(v: string | undefined, field: string): string {\n  if (!v || !v.trim()) throw new Error(`${field} is required`);\n  return v;\n}","typeGuard":"const hasValue = (v: string | null | undefined): v is string =>\n  typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Run provider setup before first use","Check the correct config scope (global vs repo)","Fail fast at startup if required keys are absent"],"tags":["config","validation","missing-value"],"backgroundTag":"missing-required-config-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"}