{"record":{"id":"ef31e968a0f60fb3","repo":"tinyhumansai/openhuman","slug":"unsupported-proxy-service-selector-selector-u","errorCode":null,"errorMessage":"Unsupported proxy service selector '{selector}'. Use tool `proxy_config` action `list_services` for valid values","messagePattern":"Unsupported proxy service selector '(.+?)'\\. Use tool `proxy_config` action `list_services` for valid values","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/config/schema/proxy.rs","lineNumber":122,"sourceCode":"\n    pub fn normalized_no_proxy(&self) -> Vec<String> {\n        normalize_no_proxy_list(self.no_proxy.clone())\n    }\n\n    pub fn validate(&self) -> Result<()> {\n        for (field, value) in [\n            (\"http_proxy\", self.http_proxy.as_deref()),\n            (\"https_proxy\", self.https_proxy.as_deref()),\n            (\"all_proxy\", self.all_proxy.as_deref()),\n        ] {\n            if let Some(url) = normalize_proxy_url_option(value) {\n                validate_proxy_url(field, &url)?;\n            }\n        }\n\n        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            );","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/config/schema/proxy.rs#L104-L140","documentation":"`ProxyConfig` validation (run at config load and on `proxy_config` updates) checks each entry of `proxy.services` against the supported selector table: concrete keys such as `provider.anthropic|compatible|copilot|gemini|glm|ollama|openai|openrouter|orcarouter`, `channel.<dingtalk|discord|lark|matrix|mattermost|qq|signal|slack|telegram|whatsapp>`, `tool.browser|composio|http_request|pushover`, `memory.embeddings`, `tunnel.custom`, plus the family wildcards `provider.*`, `channel.*`, `tool.*`, `memory.*`, `tunnel.*` — all case-insensitive. An unknown selector bails; the message points at the `proxy_config` tool's `list_services` action for the authoritative list.","triggerScenarios":"Writing `[proxy] services = [...]` (config.toml or via the proxy_config tool/UI) with a selector outside the table: misspellings like `provider.claude`, wrong prefixes like `channels.telegram`, invented keys like `tool.web`, or keys from a different core version's supported set.","commonSituations":"Hand-edited config.toml proxy sections; automation scripts assuming a service key exists; upgrades that rename or add service keys; copy-pasted configs from other setups.","solutions":["Correct the selector to a supported one — get the exact live list from the `proxy_config` tool with action `list_services` (or the SUPPORTED_PROXY_SERVICE_* constants in proxy.rs).","Use a family wildcard (`provider.*`, `channel.*`, `tool.*`, `memory.*`, `tunnel.*`) when you mean the whole family.","After a version upgrade, re-check the supported set — matching is case-insensitive but otherwise exact."],"exampleFix":"# before\n[proxy]\nenabled = true\nservices = [\"provider.claude\", \"channels.telegram\"]\n\n# after\n[proxy]\nenabled = true\nhttp_proxy = \"http://127.0.0.1:7890\"\nservices = [\"provider.anthropic\", \"channel.telegram\"]","handlingStrategy":"type-guard","validationCode":"for selector in &proxy_config.services {\n    if !is_supported_proxy_selector(selector) {\n        // reject before writing config; suggest the proxy_config tool's\n        // list_services action for the authoritative set\n    }\n}","typeGuard":"const SUPPORTED: &[&str] = &[\n    \"provider.*\", \"channel.*\", \"tool.*\", \"memory.*\", \"tunnel.*\",\n    \"provider.anthropic\", \"provider.compatible\", \"provider.copilot\", \"provider.gemini\",\n    \"provider.glm\", \"provider.ollama\", \"provider.openai\", \"provider.openrouter\", \"provider.orcarouter\",\n    \"channel.dingtalk\", \"channel.discord\", \"channel.lark\", \"channel.matrix\", \"channel.mattermost\",\n    \"channel.qq\", \"channel.signal\", \"channel.slack\", \"channel.telegram\", \"channel.whatsapp\",\n    \"tool.browser\", \"tool.composio\", \"tool.http_request\", \"tool.pushover\",\n    \"memory.embeddings\", \"tunnel.custom\",\n];\nfn is_supported_proxy_selector(s: &str) -> bool {\n    SUPPORTED.iter().any(|k| k.eq_ignore_ascii_case(s))\n}","tryCatchPattern":null,"preventionTips":["Fetch the live list via the proxy_config tool (action list_services) instead of guessing keys","Use family wildcards (provider.*, channel.*, tool.*, memory.*, tunnel.*) when you mean the whole family","Re-validate selector lists after core upgrades — keys are added and renamed over time"],"tags":["proxy","config","validation","service-selectors"],"backgroundTag":"invalid-proxy-configuration","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}