nautechsystems/nautilus_trader · error · ValueError
A BacktestNode is required for the bars_with_fills chart
Error message
A BacktestNode is required for the bars_with_fills chart
What it means
The Betfair data client's HTTP connect step failed; the message re-wraps the underlying BetfairHttpError from BetfairHttpClient::connect(), which performs interactive (non-certificate) login against the Betfair Identity API. Common causes are rejected credentials (LoginFailed), network/DNS/TLS failures, or a proxy misconfiguration. The abort happens before instruments are loaded, so the data client never reaches the streaming stage.
Source
Thrown at python/nautilus_trader/analysis/tearsheet.py:500
def generate_fills_report(self) -> pd.DataFrame:
return self._node.generate_fills_report(self._run_config_id)
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>"View on GitHub (pinned to a4b06ed870)
Solutions
- Verify credentials and app key directly (check BETFAIR_* values, confirm the app key is active)
- Test egress with curl to https://identitysso.betfair.com/api/login from the same environment and fix proxy/firewall/CA issues
- Retry with exponential backoff - transient failures during Betfair incidents recover
- If the underlying error is a login rejection (is_login_failed), fix credentials instead of retrying
Example fix
// before: first failure is fatal
self.http_client.connect().await?;
// after: distinguish auth rejection from transient failure
let mut backoff = std::time::Duration::from_secs(1);
loop {
match self.http_client.connect().await {
Ok(()) => break,
Err(e) if e.is_login_failed() => return Err(e.into()),
Err(e) if retries_left => {
tokio::time::sleep(backoff).await;
backoff *= 2;
}
Err(e) => return Err(e.into()),
}
} Defensive patterns
Strategy: retry
Validate before calling
// preflight: confirm egress and credential vars before starting the node
let ok = tokio::time::timeout(
std::time::Duration::from_secs(5),
reqwest::get("https://identitysso.betfair.com/api/login"),
).await.is_ok();
anyhow::ensure!(ok, "no egress to Betfair Identity API");
anyhow::ensure!(
std::env::var("BETFAIR_USERNAME").is_ok()
&& std::env::var("BETFAIR_PASSWORD").is_ok()
&& std::env::var("BETFAIR_APP_KEY").is_ok(),
"credentials not configured"
); Try / catch
match http_client.connect().await {
Err(e) if e.is_login_failed() => {
// credentials rejected: fix config/env, do not retry
}
Err(e) => {
// transport/transient: log and retry with exponential backoff
}
Ok(()) => { /* proceed to instrument load */ }
} Prevention
- Verify credentials and egress before market hours with a direct login test
- Allow both REST and websocket egress to Betfair domains in firewalls/proxies
- Keep container CA certificates current
- Wrap node start in bounded retry with backoff
When it happens
Trigger: Starting/connecting the data client with wrong username or password (LoginFailed from Identity API); firewall, corporate proxy, or DNS blocking identitysso.betfair.com:443; container missing CA certificates; Betfair Identity API outage during login.
Common situations: Password rotated but BETFAIR_PASSWORD stale; VPN or corporate egress blocking Betfair; Docker image without current CA certs; Betfair maintenance window; system clock skew breaking TLS validation.
Related errors
- run_config_id is required when a BacktestNode is provided
- BacktestNode state is unavailable when dispose_on_completion
- Binance Futures account state request failed: {e}
- height must be positive, was {self.height}
- pandas is required for report generation; install it with `p
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/1541b075a3d50c51.
Report an issue: GitHub.