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
- Ensure a single task owns connect/disconnect for the client; never disconnect while connect is in flight
- Retry connect() - a clean re-login repopulates the token slot
- 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
- Own connect/disconnect from a single task per client
- Never call disconnect() while connect() is in flight
- Check is_connected() before reading the session token
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
- account report contains multiple currencies
- A BacktestNode is required for the bars_with_fills chart
- height must be positive, was {self.height}
- pandas is required for report generation; install it with `p
- pandas is required for visualization; install it with `pip i
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/5d27e959c4c0f517.
Report an issue: GitHub.