nautechsystems/nautilus_trader · error · ValueError

Chart function must be callable, was {type(func)}

Error message

Chart function must be callable, was {type(func)}

What it means

BetfairDataClientConfig::validate() rejects request_rate_per_second == 0. This value sizes the rate limiter for Betting API calls made by the data client (navigation load, market catalog, etc.); zero would stall every request, so it is treated as invalid configuration rather than as unlimited. validate() also parses the currency and market-start-time filters first, so those must already be valid.

Source

Thrown at python/nautilus_trader/analysis/tearsheet.py:295

    """
    _require_not_none(name, "name")

    if not name.strip():
        raise ValueError("Chart name cannot be empty")

    if func is None:

        def decorator(f: Callable) -> Callable:
            if not callable(f):
                raise ValueError(f"Chart function must be callable, was {type(f)}")
            _CHART_REGISTRY[name] = f
            return f

        return decorator

    if not callable(func):
        raise ValueError(f"Chart function must be callable, was {type(func)}")

    _CHART_REGISTRY[name] = func
    return None


def get_chart(name: str) -> Callable:
    """
    Get registered chart function by name.

    Parameters
    ----------
    name : str
        The chart name.

    Returns
    -------
    Callable
        The chart function.

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Set a positive rate consistent with your app key's transaction limits (e.g. 5 for interactive use)
  2. Omit the field so the built-in default applies
  3. Call validate() immediately after deserializing config to catch it before node start

Example fix

// before
.request_rate_per_second(0)

// after
.request_rate_per_second(5)
Defensive patterns

Strategy: validation

Validate before calling

let config = BetfairDataClientConfig::builder()
    .request_rate_per_second(5)
    .build()?;
config.validate()?; // fails fast on zero/negative-rate style mistakes

Type guard

fn is_positive_rate(v: u32) -> bool {
    v > 0
}

Prevention

When it happens

Trigger: Explicitly setting request_rate_per_second: 0 in the data client config (or its Python object) believing it disables throttling; a config template or serialized JSON that defaults numeric fields to 0; calling validate() or building the data client through the factory with such a config.

Common situations: Copying a config schema from another adapter where 0 means unlimited; JSON deserialization of hand-edited files that initialized the field to 0; tuning attempts to maximize throughput.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/21546440deca9b94. Report an issue: GitHub.