zeroclaw-labs/zeroclaw · error · anyhow::Error
proxy.scope='services' requires a non-empty proxy.services l
Error message
proxy.scope='services' requires a non-empty proxy.services list when proxy is enabled
What it means
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.
Source
Thrown at crates/zeroclaw-config/src/schema.rs:9878
for selector in self.normalized_services() {
if !is_supported_proxy_service_selector(&selector) {
anyhow::bail!(
"Unsupported proxy service selector '{selector}'. Use tool `proxy_config` action `list_services` for valid values"
);
}
}
if self.enabled && !self.has_any_proxy_url() {
anyhow::bail!(
"Proxy is enabled but no proxy URL is configured. Set at least one of http_proxy, https_proxy, or all_proxy"
);
}
if self.enabled
&& self.scope == ProxyScope::Services
&& self.normalized_services().is_empty()
{
anyhow::bail!(
"proxy.scope='services' requires a non-empty proxy.services list when proxy is enabled"
);
}
Ok(())
}
pub fn should_apply_to_service(&self, service_key: &str) -> bool {
if !self.enabled {
return false;
}
match self.scope {
ProxyScope::Environment => false,
ProxyScope::Zeroclaw => true,
ProxyScope::Services => {
let service_key = service_key.trim().to_ascii_lowercase();
if service_key.is_empty() {View on GitHub (pinned to 88bb9c8533)
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.
Example fix
# before [proxy] enabled = true scope = "services" # after [proxy] enabled = true scope = "services" services = ["model_provider.*", "tool.*"]
Defensive patterns
Strategy: validation
Validate before calling
// scope=services + enabled requires a non-empty normalized list
if cfg.proxy.enabled
&& cfg.proxy.scope == ProxyScope::Services
&& cfg.proxy.normalized_services().is_empty()
{
// populate services or switch scope back before validate()
} Type guard
fn services_scope_satisfied(enabled: bool, is_services_scope: bool, services: &[String]) -> bool {
!enabled || !is_services_scope || services.iter().any(|s| !s.trim().is_empty())
} Try / catch
match cfg.proxy.validate() {
Err(e) if e.to_string().contains("requires a non-empty proxy.services list") => {
// add selectors like "model_provider.*" or change scope away from "services"
}
other => other,
} Prevention
- 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.
When it happens
Trigger: proxy.enabled = true, proxy.scope = "services", and proxy.services missing, set to [], or containing only blank entries.
Common situations: 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.
Related errors
- Unsupported proxy service selector '{selector}'. Use tool `p
- Proxy is enabled but no proxy URL is configured. Set at leas
- '{field}' must be a string or string[]
- apply_env only works when proxy.scope is 'environment' (curr
- matrix: `homeserver` is required
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/779230a79cc2af2b.
Report an issue: GitHub.