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

  1. 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.
  2. Verify the list is non-empty and matches the target vocabulary (same strings/ints, same casing).
  3. 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

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


AI-assisted analysis of freqtrade/freqtrade@1c8edfe4d1 (2026-08-15). Data as JSON: /api/errors/113ceb5f6ca04dfc. Report an issue: GitHub.