{"record":{"id":"173670f3d368217d","repo":"bytedance/deer-flow","slug":"channel-session-assistant-id-is-empty-use-lead-a","errorCode":null,"errorMessage":"Channel session assistant_id is empty. Use 'lead_agent' or a valid custom agent name.","messagePattern":"Channel session assistant_id is empty\\. Use 'lead_agent' or a valid custom agent name\\.","errorType":"validation","errorClass":"InvalidChannelSessionConfigError","httpStatus":null,"severity":"error","filePath":"backend/app/channels/manager.py","lineNumber":337,"sourceCode":"\n\ndef _as_dict(value: Any) -> dict[str, Any]:\n    return dict(value) if isinstance(value, Mapping) else {}\n\n\ndef _merge_dicts(*layers: Any) -> dict[str, Any]:\n    merged: dict[str, Any] = {}\n    for layer in layers:\n        if isinstance(layer, Mapping):\n            merged.update(layer)\n    return merged\n\n\ndef _normalize_custom_agent_name(raw_value: str) -> str:\n    \"\"\"Normalize legacy channel assistant IDs into valid custom agent names.\"\"\"\n    normalized = raw_value.strip().lower().replace(\"_\", \"-\")\n    if not normalized:\n        raise InvalidChannelSessionConfigError(\"Channel session assistant_id is empty. Use 'lead_agent' or a valid custom agent name.\")\n    if not CUSTOM_AGENT_NAME_PATTERN.fullmatch(normalized):\n        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.\")\n    return normalized\n\n\ndef _extract_response_text(result: dict | list) -> str:\n    \"\"\"Extract the last AI message text from a LangGraph runs.wait result.\n\n    ``runs.wait`` returns the final state dict which contains a ``messages``\n    list.  Each message is a dict with at least ``type`` and ``content``.\n\n    Handles special cases:\n    - Regular AI text responses\n    - Clarification interrupts (``ask_clarification`` tool messages)\n    \"\"\"\n    if isinstance(result, list):\n        messages = result\n    elif isinstance(result, dict):","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/channels/manager.py#L319-L355","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set assistant_id to 'lead_agent' (the default super-agent) or an existing custom agent name.","Remove the assistant_id key entirely from that channel session config so the default applies.","If it came from an IM command, re-run the binding command with a valid agent name."],"exampleFix":"# before\nchannels:\n  slack:\n    sessions:\n      default:\n        assistant_id: \"\"\n\n# after\nchannels:\n  slack:\n    sessions:\n      default:\n        assistant_id: lead_agent","handlingStrategy":"validation","validationCode":"import re\nPATTERN = re.compile(r'^[A-Za-z0-9-]+$')\n\ndef normalize_assistant_id(raw: str) -> str:\n    n = raw.strip().lower().replace('_', '-')\n    if not n or not PATTERN.fullmatch(n):\n        raise ValueError(f'invalid assistant_id {raw!r}')\n    return n","typeGuard":null,"tryCatchPattern":"try:\n    _normalize_custom_agent_name(raw)\nexcept InvalidChannelSessionConfigError as e:\n    # fall back to the default agent instead of dropping the session\n    logger.warning('%s — defaulting to lead_agent', e)\n    normalized = 'lead_agent'","preventionTips":["Offer a dropdown of registered agent slugs in channel settings instead of free text.","Omit assistant_id when you want the default rather than writing an empty string.","Validate channel session configs after every settings migration."],"tags":["channels","config","validation"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}