bytedance/deer-flow · warning · HTTPException

Unknown channel provider

Error message

Unknown channel provider

What it means

404 from _provider_config (channel_connections.py:216): the requested provider name is not a key in _PROVIDER_META (the router's allowlist of known channel providers: telegram, slack, discord, feishu, dingtalk, wechat, wecom, buzz). The allowlist exists deliberately — an unrestricted getattr would let a request-supplied name matching a non-provider config attribute (like 'enabled' or 'require_bound_identity') slip past the 404 and be dereferenced as a provider config, causing a 500.

Source

Thrown at backend/app/gateway/routers/channel_connections.py:216

        return repo

    sf = get_session_factory()
    if sf is None:
        raise HTTPException(status_code=503, detail="Channel connection persistence is not available")

    repo = ChannelConnectionRepository(sf)
    request.app.state.channel_connection_repo = repo
    return repo


def _provider_config(config: ChannelConnectionsConfig, provider: str):
    # Resolve provider configs only for known providers. An unrestricted
    # getattr would let a request-supplied name that happens to match another
    # config attribute (e.g. the "enabled" / "require_bound_identity" bool
    # fields) slip past the 404 and return a non-provider value, which callers
    # then dereference as a provider config (AttributeError -> HTTP 500).
    if provider not in _PROVIDER_META:
        raise HTTPException(status_code=404, detail="Unknown channel provider")
    provider_config = getattr(config, provider, None)
    if provider_config is None:
        raise HTTPException(status_code=404, detail="Unknown channel provider")
    return provider_config


def _runtime_channel_configured(provider: str, channels_config: dict[str, Any]) -> bool:
    runtime_config = channels_config.get(provider)
    if not isinstance(runtime_config, dict) or not runtime_config.get("enabled", False):
        return False
    return all(str(runtime_config.get(key) or "").strip() for key in _RUNTIME_REQUIREMENTS[provider])


def _runtime_unavailable_reason(provider: str) -> str:
    meta = _PROVIDER_META.get(provider)
    display_name = meta["display_name"] if meta else provider
    return f"Enter the required {display_name} credentials to connect this channel."

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Use one of the supported provider slugs exactly: telegram, slack, discord, feishu, dingtalk, wechat, wecom, buzz
  2. Fetch the provider list from the API's discovery/metadata endpoint (or _PROVIDER_META-backed listing) instead of hardcoding, so version drift cannot produce unknown names
  3. Upgrade the backend if you need a provider added in a newer release

Example fix

# before
curl /api/channels/connections/whatsapp/connect -X POST
# -> 404 Unknown channel provider

# after
curl /api/channels/connections/feishu/connect -X POST
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED = new Set(["telegram","slack","discord","feishu","dingtalk","wechat","wecom","buzz"]);
if (!SUPPORTED.has(provider)) throw new Error(`Unsupported provider: ${provider}`);

Type guard

const CHANNEL_PROVIDERS = ["telegram","slack","discord","feishu","dingtalk","wechat","wecom","buzz"] as const;
type ChannelProvider = typeof CHANNEL_PROVIDERS[number];
const isChannelProvider = (p: string): p is ChannelProvider =>
  (CHANNEL_PROVIDERS as readonly string[]).includes(p);

Try / catch

try { await connectProvider(provider) } catch (e) { if (e.status === 404 && e.detail === "Unknown channel provider") filterProviderFromUI(provider); else throw e; }

Prevention

When it happens

Trigger: Calling /api/channels/connections/{provider}/... with a provider not in the fixed set — e.g. 'whatsapp', 'email', 'ENABLED', or any typo like 'slackk'.

Common situations: Client written against docs listing providers the backend version doesn't support (provider set differs across DeerFlow versions); automated client iterating a hardcoded provider list that includes unsupported names; probing the endpoint with config-attribute names.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/ff5504e5fa73771f. Report an issue: GitHub.