TauricResearch/TradingAgents · error · ValueError

at least one analyst must be selected

Error message

at least one analyst must be selected

What it means

ValueError raised by build_analyst_execution_plan when the selected_analysts iterable is empty — the graph has no analyst nodes to execute. It is a startup sanity check: an execution plan with zero specs is meaningless, so construction fails fast with a clear message.

Source

Thrown at tradingagents/graph/analyst_execution.py:67

        clear_node="Msg Clear Fundamentals",
        tool_node="tools_fundamentals",
        report_key="fundamentals_report",
    ),
}


def build_analyst_execution_plan(
    selected_analysts: Iterable[str],
) -> AnalystExecutionPlan:
    specs: list[AnalystNodeSpec] = []
    for analyst_key in selected_analysts:
        spec = ANALYST_NODE_SPECS.get(analyst_key)
        if spec is None:
            raise ValueError(f"unknown analyst key: {analyst_key}")
        specs.append(spec)

    if not specs:
        raise ValueError("at least one analyst must be selected")

    return AnalystExecutionPlan(specs=specs)


def get_initial_analyst_node(plan: AnalystExecutionPlan) -> str:
    return plan.specs[0].agent_node


class AnalystWallTimeTracker:
    def __init__(self, plan: AnalystExecutionPlan):
        self.plan = plan
        self._started_at: dict[str, float] = {}
        self._wall_times: dict[str, float] = {}

    def mark_started(self, analyst_key: str, started_at: float | None = None) -> None:
        if analyst_key not in ANALYST_NODE_SPECS:
            raise ValueError(f"unknown analyst key: {analyst_key}")
        self._started_at.setdefault(analyst_key, monotonic() if started_at is None else started_at)

View on GitHub (pinned to a33fd4c0f1)

Solutions

  1. Ensure at least one valid analyst key is selected, e.g. ('market',).
  2. Fix config loading so a missing 'selected_analysts' key falls back to the full default set, not an empty list.
  3. Validate the config at startup before constructing TradingAgentsGraph.

Example fix

# before
TradingAgentsGraph(selected_analysts=[])

# after
TradingAgentsGraph(selected_analysts=('market', 'social', 'news', 'fundamentals'))
Defensive patterns

Strategy: validation

Validate before calling

DEFAULT_ANALYSTS = ('market', 'social', 'news', 'fundamentals')

def resolve_analysts(cfg: dict):
    selected = cfg.get('selected_analysts') or DEFAULT_ANALYSTS  # never empty
    return tuple(selected) if selected else DEFAULT_ANALYSTS

Try / catch

try:
    graph = TradingAgentsGraph(selected_analysts=selected)
except ValueError as e:
    if 'at least one analyst' in str(e):
        graph = TradingAgentsGraph(selected_analysts=('market',))
    else:
        raise

Prevention

When it happens

Trigger: Passing selected_analysts=() or [] (or an iterable that yields only entries later filtered out upstream) to TradingAgentsGraph / build_analyst_execution_plan. Also passing None-like empty collections from config, e.g. an empty YAML list under selected_analysts.

Common situations: Config-driven deployments where the analysts list is conditionally emptied; filters that remove all analysts; defaulting to an empty list when the config key is missing.

Related errors


AI-assisted analysis of TauricResearch/TradingAgents@a33fd4c0f1 (2026-08-14). Data as JSON: /api/errors/4919d8d197311291. Report an issue: GitHub.