nautechsystems/nautilus_trader · error · ValueError
Chart function must be callable, was {type(f)}
Error message
Chart function must be callable, was {type(f)} What it means
Username and password were supplied but the Betfair application key is absent. The app key is sent as the X-Application header on every API call and is mandatory alongside the session token, so BetfairCredential::resolve refuses to build a credential without it. Distinct from error 102: here login credentials exist, only the app key is missing.
Source
Thrown at python/nautilus_trader/analysis/tearsheet.py:288
... def create_custom_chart(returns: pd.Series, **kwargs) -> go.Figure:
... fig = go.Figure()
... # ... custom visualization logic
... return fig
>>>
>>> # Or called directly
>>> register_chart("another_chart", create_custom_chart)
"""
_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
----------View on GitHub (pinned to a4b06ed870)
Solutions
- Generate an app key in the Betfair developer portal and set BETFAIR_APP_KEY or the app_key config field
- Confirm the app key is activated and matches the account (live vs delayed)
- Include the app key in the startup preflight alongside username and password
Example fix
// before
.username("better".into())
.password("secret".into()) // no app_key anywhere
// after
.username("better".into())
.password("secret".into())
.app_key("xxxxxxx".into()) Defensive patterns
Strategy: validation
Validate before calling
anyhow::ensure!(
app_key.is_some() || std::env::var("BETFAIR_APP_KEY").is_ok(),
"app key missing: set BETFAIR_APP_KEY or the app_key config field"
); Type guard
fn app_key_available(app_key: Option<&str>) -> bool {
app_key.is_some() || std::env::var("BETFAIR_APP_KEY").is_ok()
} Prevention
- Generate the app key in the Betfair developer portal before first run
- Store the app key with the other two credentials in the same secret entry
- Distinguish BETFAIR_APP_KEY from similarly named variables in deploy scripts
When it happens
Trigger: Config provides username and password but no app_key while BETFAIR_APP_KEY is unset; using a differently named variable (e.g. BETFAIR_API_KEY) that does not match; new developer account where no app key has been generated yet.
Common situations: App key generated in the Betfair developer portal but never exported; delayed vs live key confusion with different variable names; secrets rotated and the app key entry dropped.
Related errors
- pandas is required for visualization; install it with `pip i
- {name} must not be None
- Chart name cannot be empty
- 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/5fbb5030192628c6.
Report an issue: GitHub.