{"record":{"id":"aabeaea6d6d271e3","repo":"Hmbown/CodeWhale","slug":"custom-providers-store-base-url-in-their-named-providers","errorCode":null,"errorMessage":"custom providers store base_url in their named [providers.<name>] table","messagePattern":"custom providers store base_url in their named \\[providers\\.<name>\\] table","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/config_persistence.rs","lineNumber":632,"sourceCode":"        ApiProvider::Mistral => Ok(\"mistral\"),\n        ApiProvider::Google => Ok(\"google\"),\n        ApiProvider::Antigravity => Ok(\"antigravity\"),\n        ApiProvider::Telecomjs => Ok(\"telecomjs\"),\n        ApiProvider::Edenai => Ok(\"edenai\"),\n        ApiProvider::Zenmux => Ok(\"zenmux\"),\n        ApiProvider::Csdn => Ok(\"csdn\"),\n        ApiProvider::Concentrate => Ok(\"concentrate\"),\n        ApiProvider::Codewhale => Ok(\"codewhale\"),\n        ApiProvider::ModelstudioTokenPlan => Ok(\"modelstudio_token_plan\"),\n        ApiProvider::ModelstudioTokenPlanAnthropic => Ok(\"modelstudio_token_plan_anthropic\"),\n        ApiProvider::ModelstudioCodingPlan => Ok(\"modelstudio_coding_plan\"),\n        ApiProvider::ModelstudioCodingPlanAnthropic => Ok(\"modelstudio_coding_plan_anthropic\"),\n        // Custom providers live under a user-chosen `[providers.<name>]` table,\n        // not a fixed key. Persisting base_url through this static-key path is\n        // out of scope for the #1519 constrained slice; users edit the named\n        // table directly.\n        ApiProvider::Custom => {\n            anyhow::bail!(\"custom providers store base_url in their named [providers.<name>] table\")\n        }\n    }\n}\n\npub(crate) fn persist_custom_provider(\n    config_path: Option<&Path>,\n    provider_id: &str,\n    base_url: &str,\n    model: Option<&str>,\n    api_key_env: Option<&str>,\n) -> anyhow::Result<PathBuf> {\n    let provider_id = normalize_custom_provider_id(provider_id)?;\n    let base_url = normalize_custom_provider_base_url(base_url)?;\n    let model = model.and_then(normalize_optional_custom_provider_field);\n    let api_key_env = api_key_env.and_then(normalize_optional_custom_provider_field);\n\n    let path = config_toml_path(config_path)?;\n    mutate_config_document(&path, |doc| {","sourceCodeStart":614,"sourceCodeEnd":650,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/config_persistence.rs#L614-L650","documentation":"Custom providers live in a user-chosen [providers.<name>] table, so there is no fixed key for ApiProvider::Custom in provider_base_url_table_key. Persisting a base_url for a custom provider through this static-key path is out of scope (the #1519 constrained slice); the function bails to prevent writing to a wrong/generic key.","triggerScenarios":"Calling persist_provider_base_url_key with ApiProvider::Custom to save a base_url for a custom provider.","commonSituations":"A script or UI tries to save a custom provider's base_url via the same helper used for built-in providers.","solutions":["Use persist_custom_provider instead, which writes the named [providers.<name>] table.","Edit the [providers.<name>] table in the config file directly."],"exampleFix":"// before\npersist_provider_base_url_key(config_path, ApiProvider::Custom, &url)?;\n// after\npersist_custom_provider(config_path, name, &url, None, None, None)?;","handlingStrategy":"validation","validationCode":"if matches!(provider, ApiProvider::Custom) { persist_custom_provider(path, name, &url, None, None, None)?; } else { persist_provider_base_url_key(path, provider, &url)?; }","typeGuard":"fn is_custom(p: ApiProvider) -> bool { matches!(p, ApiProvider::Custom) }","tryCatchPattern":"if let Err(e) = persist_provider_base_url_key(path, provider, &url) {\n    if e.to_string().contains(\"custom providers\") {\n        persist_custom_provider(path, &name, &url, None, None, None)?;\n    } else { return Err(e); }\n}","preventionTips":["Use persist_custom_provider for ApiProvider::Custom.","Remember custom providers have no fixed config key.","Edit [providers.<name>] tables directly when scripting."],"tags":["config","provider","custom-provider"],"backgroundTag":"unsupported-operation","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}