{"record":{"id":"779230a79cc2af2b","repo":"zeroclaw-labs/zeroclaw","slug":"proxy-scope-services-requires-a-non-empty-proxy","errorCode":null,"errorMessage":"proxy.scope='services' requires a non-empty proxy.services list when proxy is enabled","messagePattern":"proxy\\.scope='services' requires a non-empty proxy\\.services list when proxy is enabled","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/schema.rs","lineNumber":9878,"sourceCode":"        for selector in self.normalized_services() {\n            if !is_supported_proxy_service_selector(&selector) {\n                anyhow::bail!(\n                    \"Unsupported proxy service selector '{selector}'. Use tool `proxy_config` action `list_services` for valid values\"\n                );\n            }\n        }\n\n        if self.enabled && !self.has_any_proxy_url() {\n            anyhow::bail!(\n                \"Proxy is enabled but no proxy URL is configured. Set at least one of http_proxy, https_proxy, or all_proxy\"\n            );\n        }\n\n        if self.enabled\n            && self.scope == ProxyScope::Services\n            && self.normalized_services().is_empty()\n        {\n            anyhow::bail!(\n                \"proxy.scope='services' requires a non-empty proxy.services list when proxy is enabled\"\n            );\n        }\n\n        Ok(())\n    }\n\n    pub fn should_apply_to_service(&self, service_key: &str) -> bool {\n        if !self.enabled {\n            return false;\n        }\n\n        match self.scope {\n            ProxyScope::Environment => false,\n            ProxyScope::Zeroclaw => true,\n            ProxyScope::Services => {\n                let service_key = service_key.trim().to_ascii_lowercase();\n                if service_key.is_empty() {","sourceCodeStart":9860,"sourceCodeEnd":9896,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/schema.rs#L9860-L9896","documentation":"With proxy.enabled = true and proxy.scope = \"services\", ProxyConfig::validate requires a non-empty normalized proxy.services list. A services-scoped proxy that selects no services would route nothing, which almost certainly indicates an unfinished config; normalization means a list containing only blank strings counts as empty too.","triggerScenarios":"proxy.enabled = true, proxy.scope = \"services\", and proxy.services missing, set to [], or containing only blank entries.","commonSituations":"Switching scope from all to services without populating the list; services lists built from env expansion that came through empty; trimming entries down to nothing during cleanup.","solutions":["Populate proxy.services with valid selectors, e.g. [\"model_provider.*\", \"tool.browser\"].","If you meant to proxy everything, change proxy.scope back to the broader value instead of listing services.","Filter blank entries from programmatically-built lists before writing the config."],"exampleFix":"# before\n[proxy]\nenabled = true\nscope = \"services\"\n\n# after\n[proxy]\nenabled = true\nscope = \"services\"\nservices = [\"model_provider.*\", \"tool.*\"]","handlingStrategy":"validation","validationCode":"// scope=services + enabled requires a non-empty normalized list\nif cfg.proxy.enabled\n    && cfg.proxy.scope == ProxyScope::Services\n    && cfg.proxy.normalized_services().is_empty()\n{\n    // populate services or switch scope back before validate()\n}","typeGuard":"fn services_scope_satisfied(enabled: bool, is_services_scope: bool, services: &[String]) -> bool {\n    !enabled || !is_services_scope || services.iter().any(|s| !s.trim().is_empty())\n}","tryCatchPattern":"match cfg.proxy.validate() {\n    Err(e) if e.to_string().contains(\"requires a non-empty proxy.services list\") => {\n        // add selectors like \"model_provider.*\" or change scope away from \"services\"\n    }\n    other => other,\n}","preventionTips":["When switching scope to services, populate the list in the same edit.","Filter blank strings from generated services lists — normalization treats them as empty.","Use a family wildcard (\"tool.*\") rather than leaving the list empty to mean everything."],"tags":["proxy","config","validation","scope"],"backgroundTag":"proxy-scope-misconfigured","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}