nautechsystems/nautilus_trader · error · ValueError

run_config_id is required when a BacktestNode is provided

Error message

run_config_id is required when a BacktestNode is provided

What it means

After a successful HTTP login, BetfairHttpClient::session_token() returned None while the data client was setting up its market stream. session_token() reads a shared slot that connect() fills on login and that disconnect()/reconnect() clear, so a None here means the session was cleared between login and read (a concurrent disconnect or reconnect race), not a Betfair-side rejection.

Source

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


def _create_tearsheet_from_result(
    result: BacktestResult,
    node: BacktestNode | None,
    run_config_id: str | None,
    currency,
    output_path: str | None,
    title: str,
    config,
    benchmark_returns: pd.Series | None,
    benchmark_name: str,
) -> str | None:
    resolved_run_config_id = run_config_id or result.run_config_id
    needs_engine = config is not None and "bars_with_fills" in config.chart_names
    if needs_engine and node is None:
        raise ValueError("A BacktestNode is required for the bars_with_fills chart")
    if node is not None and resolved_run_config_id is None:
        raise ValueError("run_config_id is required when a BacktestNode is provided")
    if node is not None and resolved_run_config_id is not None:
        _validate_result_node_state(node, resolved_run_config_id)

    engine_view = (
        _BacktestNodeEngineView(node, resolved_run_config_id)
        if node is not None and resolved_run_config_id is not None
        else None
    )
    returns = _result_returns_series(result)
    run_info = _result_run_info(result)
    account_info = _result_account_info(result, node, resolved_run_config_id, currency)

    if title == "NautilusTrader Backtest Results":
        run_started = _format_optional_iso8601(result.run_started)
        title = f"<b>NautilusTrader</b> v{NAUTILUS_VERSION} - Backtest Results"
        title += f"<br><sub>Run started: {run_started}</sub>"

    return create_tearsheet_from_stats(

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Ensure a single task owns connect/disconnect for the client; never disconnect while connect is in flight
  2. Retry connect() - a clean re-login repopulates the token slot
  3. Check is_connected() before requesting a restart to avoid racing states

Example fix

// before
let token = self.http_client.session_token().await
    .ok_or_else(|| anyhow::anyhow!("No session token after login"))?;

// after: re-login once if the slot was cleared by a race
let token = match self.http_client.session_token().await {
    Some(t) => t,
    None => {
        self.http_client.reconnect().await?;
        self.http_client.session_token().await
            .ok_or_else(|| anyhow::anyhow!("No session token after login"))?
    }
};
Defensive patterns

Strategy: validation

Validate before calling

if !http_client.is_connected().await {
    anyhow::bail!("Betfair HTTP session missing; connect before requesting the token");
}
let token = http_client.session_token().await
    .ok_or_else(|| anyhow::anyhow!("session token cleared by a concurrent disconnect"))?;

Type guard

async fn has_live_session(client: &BetfairHttpClient) -> bool {
    client.is_connected().await
}

Try / catch

match http_client.session_token().await {
    Some(t) => { /* proceed with stream setup */ }
    None => {
        // session cleared mid-connect: re-login and retry once, else surface the race
        http_client.reconnect().await?;
    }
}

Prevention

When it happens

Trigger: Another task calls disconnect() or reconnect() on the same BetfairHttpClient while DataClient::connect() is between login and stream setup; stopping the node mid-connect; sharing one HTTP client across components that race on session state.

Common situations: Shutdown signal arriving during startup; two owners driving the same client (e.g. data and exec clients built on one HTTP client); supervision logic that disconnects on a timeout while connect is still in flight.

Related errors


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