From 34aeca61ad996ecf7920df67642dbbe3cc63c35a Mon Sep 17 00:00:00 2001 From: centdix <40307056+centdix@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:08:30 +0100 Subject: [PATCH] fix: handle empty base_url and region strings in AI providers (#7719) When creating an Anthropic resource with "standard platform", the resource JSON may contain `"base_url": ""` rather than omitting the field. Serde deserializes this as `Some("")`, which bypassed the fallback logic and caused "relative URL without a base" errors. Similarly, AWS Bedrock with an empty region string would produce an invalid URL like `https://bedrock-runtime..amazonaws.com`. Filter out empty strings when checking for custom base_url and region values, allowing the default URLs to be used correctly. Co-authored-by: Claude Opus 4.5 --- backend/windmill-common/src/ai_providers.rs | 24 +++++++++------------ 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/backend/windmill-common/src/ai_providers.rs b/backend/windmill-common/src/ai_providers.rs index 48b2ef8281..b156002dc8 100644 --- a/backend/windmill-common/src/ai_providers.rs +++ b/backend/windmill-common/src/ai_providers.rs @@ -39,8 +39,8 @@ impl AIProvider { region: Option, db: &DB, ) -> Result { - // If a base URL is provided in the resource, use it - if let Some(base_url) = resource_base_url { + // If a base URL is provided in the resource, use it (ignore empty strings) + if let Some(base_url) = resource_base_url.filter(|s| !s.is_empty()) { return Ok(base_url); } @@ -74,29 +74,25 @@ impl AIProvider { AIProvider::TogetherAI => Ok("https://api.together.xyz/v1".to_string()), AIProvider::Anthropic => Ok("https://api.anthropic.com/v1".to_string()), AIProvider::Mistral => Ok("https://api.mistral.ai/v1".to_string()), - p @ (AIProvider::CustomAI | AIProvider::AzureOpenAI) => { - if let Some(base_url) = resource_base_url { - Ok(base_url) - } else { - Err(Error::BadRequest(format!( - "{:?} provider requires a base URL in the resource", - p - ))) - } - } + p @ (AIProvider::CustomAI | AIProvider::AzureOpenAI) => Err(Error::BadRequest( + format!("{:?} provider requires a base URL in the resource", p), + )), AIProvider::AWSBedrock => { #[cfg(feature = "bedrock")] { Ok(format!( "https://bedrock-runtime.{}.amazonaws.com", - region.unwrap_or_else(|| "us-east-1".to_string()) + region + .filter(|s| !s.is_empty()) + .unwrap_or_else(|| "us-east-1".to_string()) )) } #[cfg(not(feature = "bedrock"))] { let _ = region; Err(Error::BadRequest( - "AWS Bedrock support is not enabled. Build with 'bedrock' feature.".to_string() + "AWS Bedrock support is not enabled. Build with 'bedrock' feature." + .to_string(), )) } }