nautechsystems/nautilus_trader · error · ValueError
{name} must not be None
Error message
{name} must not be None What it means
A username was supplied but no password, so the credential triple is incomplete and BetfairCredential::resolve rejects it instead of attempting a doomed login. Note the resolution order: when any value is provided in config, the environment fallback is skipped entirely for the triple, so setting only username in config disables BETFAIR_PASSWORD from the environment.
Source
Thrown at python/nautilus_trader/analysis/tearsheet.py:92
PLOTLY_AVAILABLE = True
except ImportError:
PLOTLY_AVAILABLE = False
if not TYPE_CHECKING:
go = None # type: ignore[assignment]
TRADING_DAYS_PER_YEAR = 252
_STATIC_IMAGE_SUFFIXES = frozenset({".png", ".jpg", ".jpeg", ".webp", ".svg", ".pdf"})
_CHART_REGISTRY: dict[str, Callable] = {}
def _require_not_none(value: Any, name: str) -> None:
if value is None:
raise ValueError(f"{name} must not be None")
def _format_optional_iso8601(timestamp_ns: int | None) -> str:
if timestamp_ns is None:
return "N/A"
return unix_nanos_to_iso8601(timestamp_ns, nanos_precision=False)
def _format_optional_duration(start_ns: int | None, end_ns: int | None) -> str:
if start_ns is None or end_ns is None:
return "N/A"
return str(pd.Timedelta(end_ns - start_ns, unit="ns"))
def _to_returns_series(returns) -> pd.Series:
pandas = _require_pandas()
if returns is None:
return pandas.Series(dtype=float)View on GitHub (pinned to a4b06ed870)
Solutions
- Provide the password alongside the username (config field or BETFAIR_PASSWORD)
- Supply all three credentials from one source - all in config or all via environment - to avoid partial resolution
- Assert credential completeness at startup before building the client
Example fix
// before
.username("better".into()) // password assumed from env (never read)
// after
.username("better".into())
.password("secret".into())
.app_key("xxxxxxx".into()) Defensive patterns
Strategy: validation
Validate before calling
anyhow::ensure!(
username.is_some() == password.is_some(),
"username and password must be provided together (got username={:?})",
username
); Type guard
fn credential_pair_complete(username: Option<&str>, password: Option<&str>) -> bool {
username.is_some() == password.is_some()
} Prevention
- Never split the credential triple between config and environment
- Treat partial credentials as a config bug caught in review
- Log which credential source (config vs env) was used at startup
When it happens
Trigger: Config sets username while password is left unset (expecting env fallback, which does not happen for partial config); or the environment has only BETFAIR_USERNAME set; password key misspelled in a YAML config.
Common situations: Splitting credentials between config and environment; renaming credential keys during refactors; a secret manager injecting only some variables; partially migrated config files.
Related errors
- Chart name cannot be empty
- 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
- Chart function must be callable, was {type(f)}
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/d80ca27c5271f06c.
Report an issue: GitHub.