TauricResearch/TradingAgents · error · ValueError

llm_max_retries must be >= 0, got {n}

Error message

llm_max_retries must be >= 0, got {n}

What it means

ValueError raised by _coerce_max_retries when the value converts to an int but is negative. Retry counts of -1 are meaningless for the LLM retry loop, so a negative value fails at startup — deliberately, so retries are never silently disabled by a bad config.

Source

Thrown at tradingagents/graph/trading_graph.py:61

logger = logging.getLogger(__name__)


def _coerce_max_retries(value):
    """Validate an ``llm_max_retries`` value to a non-negative int.

    Accepts an int or a numeric string (env vars arrive as strings). Rejects
    booleans and negatives loudly so a misconfiguration fails at startup rather
    than silently disabling retries.
    """
    if isinstance(value, bool):
        raise ValueError(f"llm_max_retries must be an integer, not a boolean: {value!r}")
    try:
        n = int(value)
    except (TypeError, ValueError) as exc:
        raise ValueError(f"llm_max_retries must be an integer, got {value!r}") from exc
    if n < 0:
        raise ValueError(f"llm_max_retries must be >= 0, got {n}")
    return n


class TradingAgentsGraph:
    """Main class that orchestrates the trading agents framework."""

    def __init__(
        self,
        selected_analysts=("market", "social", "news", "fundamentals"),
        debug=False,
        config: dict[str, Any] = None,
        callbacks: list | None = None,
    ):
        """Initialize the trading agents graph and components.

        Args:
            selected_analysts: List of analyst types to include
            debug: Whether to run in debug mode

View on GitHub (pinned to a33fd4c0f1)

Solutions

  1. Use 0 to disable retries, or a positive count like 3.
  2. Fix config generation that computes the value arithmetically and can go negative.
  3. Document 0-means-no-retries in your deployment instead of -1.

Example fix

# before
TradingAgentsGraph(config={**DEFAULT_CONFIG, 'llm_max_retries': -1})

# after
TradingAgentsGraph(config={**DEFAULT_CONFIG, 'llm_max_retries': 0})  # 0 = no retries
Defensive patterns

Strategy: validation

Validate before calling

def resolve_max_retries(cfg: dict, default: int = 3) -> int:
    value = cfg.get('llm_max_retries', default)
    n = int(value)
    if n < 0:
        raise ValueError('use 0 to disable retries, not a negative count')
    return n

Try / catch

try:
    graph = TradingAgentsGraph(config=config)
except ValueError as e:
    if 'llm_max_retries must be >= 0' in str(e):
        config['llm_max_retries'] = 0
        graph = TradingAgentsGraph(config=config)
    else:
        raise

Prevention

When it happens

Trigger: Passing llm_max_retries=-1 (or '-1' as a string from an env var) to TradingAgentsGraph. int('-1') succeeds, then the n < 0 check raises.

Common situations: Using -1 as an 'infinite/disabled' sentinel from other tools' conventions; arithmetic in config scripts that underflows to a negative count; copy-pasted env values.

Related errors


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