tinyhumansai/openhuman · error

Unsupported proxy service selector '{selector}'. Use tool `p

Error message

Unsupported proxy service selector '{selector}'. Use tool `proxy_config` action `list_services` for valid values

What it means

`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.

Source

Thrown at src/openhuman/config/schema/proxy.rs:122

    pub fn normalized_no_proxy(&self) -> Vec<String> {
        normalize_no_proxy_list(self.no_proxy.clone())
    }

    pub fn validate(&self) -> Result<()> {
        for (field, value) in [
            ("http_proxy", self.http_proxy.as_deref()),
            ("https_proxy", self.https_proxy.as_deref()),
            ("all_proxy", self.all_proxy.as_deref()),
        ] {
            if let Some(url) = normalize_proxy_url_option(value) {
                validate_proxy_url(field, &url)?;
            }
        }

        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"
            );

View on GitHub (pinned to 7491200858)

Solutions

  1. 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).
  2. Use a family wildcard (`provider.*`, `channel.*`, `tool.*`, `memory.*`, `tunnel.*`) when you mean the whole family.
  3. After a version upgrade, re-check the supported set — matching is case-insensitive but otherwise exact.

Example fix

# before
[proxy]
enabled = true
services = ["provider.claude", "channels.telegram"]

# after
[proxy]
enabled = true
http_proxy = "http://127.0.0.1:7890"
services = ["provider.anthropic", "channel.telegram"]
Defensive patterns

Strategy: type-guard

Validate before calling

for selector in &proxy_config.services {
    if !is_supported_proxy_selector(selector) {
        // reject before writing config; suggest the proxy_config tool's
        // list_services action for the authoritative set
    }
}

Type guard

const SUPPORTED: &[&str] = &[
    "provider.*", "channel.*", "tool.*", "memory.*", "tunnel.*",
    "provider.anthropic", "provider.compatible", "provider.copilot", "provider.gemini",
    "provider.glm", "provider.ollama", "provider.openai", "provider.openrouter", "provider.orcarouter",
    "channel.dingtalk", "channel.discord", "channel.lark", "channel.matrix", "channel.mattermost",
    "channel.qq", "channel.signal", "channel.slack", "channel.telegram", "channel.whatsapp",
    "tool.browser", "tool.composio", "tool.http_request", "tool.pushover",
    "memory.embeddings", "tunnel.custom",
];
fn is_supported_proxy_selector(s: &str) -> bool {
    SUPPORTED.iter().any(|k| k.eq_ignore_ascii_case(s))
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/ef31e968a0f60fb3. Report an issue: GitHub.