bytedance/deer-flow · error · InvalidChannelSessionConfigError

Invalid channel session assistant_id {raw_value!r}. Use 'lea

Error message

Invalid channel session assistant_id {raw_value!r}. Use 'lead_agent' or a custom agent name containing only letters, digits, and hyphens.

What it means

After normalization, assistant_id must fullmatch ^[A-Za-z0-9-]+$ (CUSTOM_AGENT_NAME_PATTERN). Values containing dots, slashes, spaces, at-signs, CJK characters, or other symbols after the underscore->hyphen mapping raise this error. The strict pattern exists because the name is resolved against registered custom agents and used in routing.

Source

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

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):
        messages = result.get("messages", [])
    else:

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Use the custom agent's slug exactly as shown in the agents UI — letters, digits, hyphens only (e.g. 'research-agent').
  2. Replace spaces/dots with hyphens: 'code.review.v2' -> 'code-review-v2'.
  3. Use 'lead_agent' (normalizes fine) for the default super-agent.

Example fix

# before
assistant_id: "Code Review v2"

# after
assistant_id: "code-review-v2"
Defensive patterns

Strategy: type-guard

Validate before calling

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

def valid_assistant_id(raw: str) -> bool:
    n = raw.strip().lower().replace('_', '-')
    return bool(CUSTOM_AGENT_NAME_PATTERN.fullmatch(n))

Type guard

function isValidAssistantId(raw: string): boolean {
  const n = raw.trim().toLowerCase().replaceAll('_', '-');
  return /^[A-Za-z0-9-]+$/.test(n);
}

Try / catch

try:
    session.assistant_id = _normalize_custom_agent_id(user_input)
except InvalidChannelSessionConfigError as e:
    reply_to_channel(f'{e}')  # actionable message back to the IM user

Prevention

When it happens

Trigger: assistant_id set to something like 'agent.one', 'Agent A', '@bot', 'café-agent', or an email address. Normalization only fixes case and underscores, so any remaining non-[A-Za-z0-9-] character triggers the raise when the session config is loaded or updated.

Common situations: Copying a display name or email instead of the agent's slug; renaming a custom agent to include spaces and not updating channel bindings; pasting with a trailing period or comma.

Related errors


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