{"record":{"id":"e75498b0f1f0f582","repo":"gitbutlerapp/gitbutler","slug":"could-not-determine-openai-credential-source","errorCode":null,"errorMessage":"Could not determine OpenAI credential source","messagePattern":"Could not determine OpenAI credential source","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/but/src/command/config.rs","lineNumber":1593,"sourceCode":"        (\"Ollama\", LLMProviderKind::Ollama),\n        (\"LM Studio\", LLMProviderKind::LMStudio),\n        (\"OpenRouter\", LLMProviderKind::OpenRouter)\n    ];\n    let provider = inout\n        .prompt_select(\"Select an AI provider\", &providers)?\n        .cloned()\n        .ok_or_else(|| anyhow::anyhow!(\"Could not determine selected AI provider\"))?;\n\n    match provider {\n        LLMProviderKind::OpenAi => {\n            let key_options = nonempty::nonempty![\n                (\"Use GitButler API\", AiKeyOption::ButlerApi),\n                (\"Bring your own key\", AiKeyOption::BringYourOwn)\n            ];\n            let key_option = inout\n                .prompt_select(\"Select OpenAI credential source\", &key_options)?\n                .copied()\n                .ok_or_else(|| anyhow::anyhow!(\"Could not determine OpenAI credential source\"))?;\n\n            let model = inout.prompt(\"Preferred OpenAI model (leave empty for default):\")?;\n            let endpoint = inout.prompt(\"Custom endpoint URL (optional):\")?;\n\n            let secret = if matches!(key_option, AiKeyOption::BringYourOwn) {\n                Some(\n                    inout\n                        .prompt_secret(\"Enter OpenAI API key:\")?\n                        .context(\"No API key provided. Aborting configuration.\")?,\n                )\n            } else {\n                None\n            };\n\n            apply_openai_config(repo, scope, key_option, model, endpoint, secret)?;\n        }\n        LLMProviderKind::Anthropic => {\n            let key_options = nonempty::nonempty![","sourceCodeStart":1575,"sourceCodeEnd":1611,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/config.rs#L1575-L1611","documentation":"After choosing OpenAI as AI provider, the CLI asks for a credential source ('Use GitButler API' vs 'Bring your own key') via prompt_select; this error fires when that picker is cancelled and returns None. It guards the next step (model/endpoint/secret prompts) from running without a credential decision.","triggerScenarios":"Selecting OpenAI in AI config, then pressing Esc at the 'Select OpenAI credential source' picker.","commonSituations":"User undecided between the proxied GitButler key and a personal key; aborting to go create an OpenAI key first.","solutions":["Pick 'Use GitButler API' if you authenticate through GitButler — no key entry needed.","Pick 'Bring your own key' after creating the key at platform.openai.com; the following prompt asks for it.","Re-run the config command to restart the flow."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match configure_ai(out).await {\n    Err(e) if e.to_string().contains(\"OpenAI credential source\") => { Ok(()) }\n    other => other,\n}","preventionTips":["Decide GitButler API vs own key before the prompt.","Create the OpenAI key first if bringing your own."],"tags":["interactive","picker","openai","credentials"],"backgroundTag":"prompt-cancelled","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}