freqtrade/freqtrade · error · ValueError
self.class_names is empty, set self.freqai.class_names = ['c
Error message
self.class_names is empty, set self.freqai.class_names = ['class a', 'class b', 'class c'] inside IStrategy.set_freqai_targets method.
What it means
get_class_names() on the PyTorch classifier base returns self.class_names, which is populated from the strategy's configuration. If it is empty, there is no way to know the label vocabulary, so a ValueError is raised telling the user to set self.freqai.class_names inside IStrategy.set_freqai_targets. The message includes an inline example of the expected assignment.
Source
Thrown at freqtrade/freqai/base_models/BasePyTorchClassifier.py:153
return [self.index_to_class_name[x.item()] for x in class_ints]
def init_class_names_to_index_mapping(self, class_names):
self.class_name_to_index = {s: i for i, s in enumerate(class_names)}
self.index_to_class_name = {i: s for i, s in enumerate(class_names)}
logger.info(f"encoded class name to index: {self.class_name_to_index}")
def convert_label_column_to_int(
self,
data_dictionary: dict[str, pd.DataFrame],
dk: FreqaiDataKitchen,
class_names: list[str],
):
self.init_class_names_to_index_mapping(class_names)
self.encode_class_names(data_dictionary, dk, class_names)
def get_class_names(self) -> list[str]:
if not self.class_names:
raise ValueError(
"self.class_names is empty, "
"set self.freqai.class_names = ['class a', 'class b', 'class c'] "
"inside IStrategy.set_freqai_targets method."
)
return self.class_names
def train(self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs) -> Any:
"""
Filter the training data and train a model to it. Train makes heavy use of the datakitchen
for storing, saving, loading, and analyzing the data.
:param unfiltered_df: Full dataframe for the current training period
:return:
:model: Trained model which can be used to inference (self.predict)
"""
logger.info(f"-------------------- Starting training {pair} --------------------")
View on GitHub (pinned to 1c8edfe4d1)
Solutions
- Inside your strategy's set_freqai_targets, add self.freqai.class_names = ['class a', 'class b', ...] matching the exact values written to the target column.
- Verify the list is non-empty and matches the target vocabulary (same strings/ints, same casing).
- Retrain so the class names are persisted into model metadata for later prediction.
Example fix
# before
def set_freqai_targets(self, dataframe, metadata, **kwargs):
dataframe['&-target'] = (dataframe['close'].shift(-self.freqai_info['feature_parameters']['label_period_candles']) > dataframe['close']).astype(int)
return dataframe
# after
def set_freqai_targets(self, dataframe, metadata, **kwargs):
self.freqai.class_names = ['down', 'up']
dataframe['&-target'] = (dataframe['close'].shift(-1) > dataframe['close']).map({0: 'down', 1: 'up'})
return dataframe Defensive patterns
Strategy: validation
Validate before calling
class_names = getattr(self.freqai, 'class_names', None)
if not class_names:
raise RuntimeError('Set self.freqai.class_names in set_freqai_targets before training.') Type guard
def has_freqai_class_names(strategy) -> bool:
return bool(getattr(getattr(strategy, 'freqai', None), 'class_names', None)) Prevention
- Set self.freqai.class_names as the first line of set_freqai_targets in every classifier strategy.
- Add a smoke-test that instantiates the strategy and asserts class_names is non-empty.
When it happens
Trigger: Running a PyTorch classification model (e.g. PyTorchClassifierModel) whose strategy never assigns self.freqai.class_names, or assigns an empty list. The call typically occurs during train() setup when the model queries the class vocabulary.
Common situations: New classification strategy built by copying a regression template; refactoring set_freqai_targets and dropping the assignment; setting class_names on the wrong object (e.g. self.class_names instead of self.freqai.class_names).
Related errors
- Missing class names. self.model.model_meta_data['class_names
- You are trying to use a FreqAI strategy with process_only_ne
- Either `n_steps` or `n_epochs` should be set.
- Using analyze-per-epoch parameter is not supported with a Fr
- Main timeframe of {main_tf} must be smaller or equal to Freq
AI-assisted analysis of freqtrade/freqtrade@1c8edfe4d1 (2026-08-15).
Data as JSON: /api/errors/113ceb5f6ca04dfc.
Report an issue: GitHub.