{"record":{"id":"249ce63373134004","repo":"BoundaryML/baml","slug":"strategy-provider-is-empty","errorCode":null,"errorMessage":"Strategy provider is empty: {}","messagePattern":"Strategy provider is empty: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/internal/llm_client/llm_provider.rs","lineNumber":87,"sourceCode":"        chat: &[RenderedChatMessage],\n        ctx: &RuntimeContext,\n        client_lookup: &'a dyn InternalClientLookup<'a>,\n    ) -> Result<serde_json::Map<String, serde_json::Value>> {\n        match self {\n            LLMProvider::Primitive(provider) => provider.chat_to_message(chat),\n\n            // Return the first node's provider implementation.\n            LLMProvider::Strategy(provider) => {\n                let orchestrator = provider.iter_orchestrator(\n                    &mut Default::default(),\n                    Default::default(),\n                    ctx,\n                    client_lookup,\n                )?;\n\n                orchestrator\n                    .first()\n                    .ok_or(anyhow::anyhow!(\"Strategy provider is empty: {}\", provider))?\n                    .provider\n                    .chat_to_message(chat)\n            }\n        }\n    }\n\n    pub fn completion_to_provider_body<'a>(\n        &self,\n        prompt: &str,\n        ctx: &RuntimeContext,\n        client_lookup: &'a dyn InternalClientLookup<'a>,\n    ) -> Result<serde_json::Map<String, serde_json::Value>> {\n        match self {\n            LLMProvider::Primitive(provider) => provider.completion_to_provider_body(prompt),\n\n            LLMProvider::Strategy(provider) => {\n                let orchestrator = provider.iter_orchestrator(\n                    &mut Default::default(),","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/internal/llm_client/llm_provider.rs#L69-L105","documentation":"In llm_provider's chat_to_message, for a strategy-style provider the orchestrator resolves the strategy to a list of candidate clients, and .first() must yield one. If the orchestrator returns an empty list for the provider name, this error fires: the named strategy resolved to zero providers, so there is nothing to send the chat to.","triggerScenarios":"Calling chat_to_message on a provider whose name refers to a strategy (retry/fallback strategy) but whose strategy configuration produces an empty client list — e.g. the strategy's clients array is empty or all referenced clients failed to resolve.","commonSituations":"A baml.config strategy block referencing clients by name that are not defined or were filtered out; an empty clients list under a strategy; typo'd strategy name causing resolution to silently produce no entries.","solutions":["Ensure the strategy in baml.config declares at least one client in its clients array.","Verify every client referenced by the strategy exists and is spelled correctly.","Check the strategy name passed as provider matches the strategy defined in configuration.","Add a default/primary client instead of an empty strategy so requests always have a target."],"exampleFix":"// before (baml)\nclient Strategy {\n  provider retry\n  strategy {\n    // clients list is empty\n  }\n}\n// after (baml)\nclient Strategy {\n  provider retry\n  strategy {\n    ClientA\n    ClientB\n  }\n}","handlingStrategy":"validation","validationCode":"// Before using a strategy provider, verify it resolves to at least one client.\nfn validate_strategy(config: &RuntimeConfig, strategy_name: &str) -> Result<(), String> {\n    let strategy = config.llm_clients.iter().find(|c| c.name == strategy_name)\n        .ok_or_else(|| format!(\"strategy `{}` not defined\", strategy_name))?;\n    if strategy.clients.is_empty() {\n        return Err(format!(\"strategy `{}` has no clients\", strategy_name));\n    }\n    for c in &strategy.clients {\n        if !config.llm_clients.iter().any(|k| &k.name == c) {\n            return Err(format!(\"strategy `{}` references unknown client `{}`\", strategy_name, c));\n        }\n    }\n    Ok(())\n}","typeGuard":"fn strategy_has_clients(cfg: &RuntimeConfig, name: &str) -> bool {\n    cfg.llm_clients.iter()\n        .find(|c| c.name == name)\n        .map_or(false, |c| !c.clients.is_empty())\n}","tryCatchPattern":"match provider.chat_to_message(chat) {\n    Ok(m) => m,\n    Err(e) if e.to_string().starts_with(\"Strategy provider is empty\") => {\n        eprintln!(\"Fix the strategy's clients list in baml.config\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always define at least one client inside every retry/fallback strategy.","Cross-check client names referenced by strategies against declared clients at config load time.","Fall back to a direct (non-strategy) client when a strategy resolves to nothing.","Validate baml.config fully at startup with unit tests covering each strategy."],"tags":["rust","configuration","strategy","orchestration"],"backgroundTag":"empty-result-set","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}