bytedance/deer-flow · error · InvalidChannelSessionConfigError

Channel session assistant_id is empty. Use 'lead_agent' or a

Error message

Channel session assistant_id is empty. Use 'lead_agent' or a valid custom agent name.

What it means

Channel session configs carry an assistant_id naming which agent handles a channel conversation. _normalize_custom_agent_name strips whitespace, lowercases, and maps underscores to hyphens to accept legacy IDs; if the result is the empty string, this InvalidChannelSessionConfigError (a ValueError subclass) is raised, telling the operator to use 'lead_agent' or a custom agent name.

Source

Thrown at backend/app/channels/manager.py:337


def _as_dict(value: Any) -> dict[str, Any]:
    return dict(value) if isinstance(value, Mapping) else {}


def _merge_dicts(*layers: Any) -> dict[str, Any]:
    merged: dict[str, Any] = {}
    for layer in layers:
        if isinstance(layer, Mapping):
            merged.update(layer)
    return merged


def _normalize_custom_agent_name(raw_value: str) -> str:
    """Normalize legacy channel assistant IDs into valid custom agent names."""
    normalized = raw_value.strip().lower().replace("_", "-")
    if not normalized:
        raise InvalidChannelSessionConfigError("Channel session assistant_id is empty. Use 'lead_agent' or a valid custom agent name.")
    if not CUSTOM_AGENT_NAME_PATTERN.fullmatch(normalized):
        raise InvalidChannelSessionConfigError(f"Invalid channel session assistant_id {raw_value!r}. Use 'lead_agent' or a custom agent name containing only letters, digits, and hyphens.")
    return normalized


def _extract_response_text(result: dict | list) -> str:
    """Extract the last AI message text from a LangGraph runs.wait result.

    ``runs.wait`` returns the final state dict which contains a ``messages``
    list.  Each message is a dict with at least ``type`` and ``content``.

    Handles special cases:
    - Regular AI text responses
    - Clarification interrupts (``ask_clarification`` tool messages)
    """
    if isinstance(result, list):
        messages = result
    elif isinstance(result, dict):

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Set assistant_id to 'lead_agent' (the default super-agent) or an existing custom agent name.
  2. Remove the assistant_id key entirely from that channel session config so the default applies.
  3. If it came from an IM command, re-run the binding command with a valid agent name.

Example fix

# before
channels:
  slack:
    sessions:
      default:
        assistant_id: ""

# after
channels:
  slack:
    sessions:
      default:
        assistant_id: lead_agent
Defensive patterns

Strategy: validation

Validate before calling

import re
PATTERN = re.compile(r'^[A-Za-z0-9-]+$')

def normalize_assistant_id(raw: str) -> str:
    n = raw.strip().lower().replace('_', '-')
    if not n or not PATTERN.fullmatch(n):
        raise ValueError(f'invalid assistant_id {raw!r}')
    return n

Try / catch

try:
    _normalize_custom_agent_name(raw)
except InvalidChannelSessionConfigError as e:
    # fall back to the default agent instead of dropping the session
    logger.warning('%s — defaulting to lead_agent', e)
    normalized = 'lead_agent'

Prevention

When it happens

Trigger: A channel session config (persisted per channel/conversation, e.g. via IM commands or the channel settings API) has assistant_id set to '', ' ', or a value made only of underscores/whitespace that normalizes to empty. Raised when the channel manager loads or updates that session config.

Common situations: Editing a channel's agent binding and clearing the field; a migration writing empty strings instead of omitting the key; an IM command that sets the assistant to a blank value.

Related errors


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