HKUDS/Vibe-Trading · error · ValueError

agent config 'channels.feishu' must be an object

Error message

agent config 'channels.feishu' must be an object

What it means

Inside the channels object, the 'feishu' entry must itself be a JSON object so credentials (app_id, app_secret, domain) can be merged in. A non-object value triggers this ValueError instead of overwriting user data.

Source

Thrown at agent/src/channels/feishu.py:74

    from src.config.loader import _read_config_file
    from src.config.paths import get_config_path

    path = config_path or get_config_path()
    if path.suffix.lower() != ".json":
        raise ValueError(
            "Feishu QR login requires a JSON agent config; use "
            "~/.vibe-trading/agent.json"
        )

    payload: dict[str, Any] = {}
    if path.exists():
        payload = _read_config_file(path)
    channels = payload.setdefault("channels", {})
    if not isinstance(channels, dict):
        raise ValueError("agent config 'channels' must be an object")
    section = channels.setdefault("feishu", {})
    if not isinstance(section, dict):
        raise ValueError("agent config 'channels.feishu' must be an object")
    section.update(
        {
            "enabled": True,
            "app_id": app_id,
            "app_secret": app_secret,
            "domain": domain,
        }
    )

    path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
    content = (json.dumps(payload, ensure_ascii=False, indent=2) + "\n").encode("utf-8")
    fd, temporary = tempfile.mkstemp(
        dir=path.parent,
        prefix=f".{path.name}.",
        suffix=".tmp",
    )
    try:
        try:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Change the entry to an object: "channels": {"feishu": {}} — login will fill in credentials
  2. Remove the malformed feishu entry entirely and let setdefault recreate it as an object

Example fix

// before
"channels": {"feishu": true}
// after
"channels": {"feishu": {"enabled": true}}
Defensive patterns

Strategy: type-guard

Validate before calling

ch = cfg.setdefault('channels', {})
if 'feishu' in ch and not isinstance(ch['feishu'], dict): raise ValueError('channels.feishu must be an object')

Type guard

def has_valid_feishu_section(cfg: dict) -> bool:
    ch = cfg.get('channels', {})
    return isinstance(ch, dict) and ('feishu' not in ch or isinstance(ch['feishu'], dict))

Prevention

When it happens

Trigger: agent.json has "channels": {"feishu": true} or "feishu": "enabled" — any non-object — when QR login persists credentials.

Common situations: Minimal hand-written configs that use booleans/strings as toggles for channels; copy-paste from older config examples with a flat schema.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/9e4e67fe9f3ff89e. Report an issue: GitHub.