{"record":{"id":"9ab5ff393a51a2ec","repo":"freqtrade/freqtrade","slug":"found-non-defined-labels-non-defined-labels-ex","errorCode":null,"errorMessage":"Found non defined labels: {non_defined_labels}, expecting labels: {class_names}","messagePattern":"Found non defined labels: (.+?), expecting labels: (.+?)","errorType":"exception","errorClass":"OperationalException","httpStatus":null,"severity":"error","filePath":"freqtrade/freqai/base_models/BasePyTorchClassifier.py","lineNumber":125,"sourceCode":"        \"\"\"\n        encode class name, str -> int\n        assuming first column of *_labels data frame to be the target column\n        containing the class names\n        \"\"\"\n\n        target_column_name = dk.label_list[0]\n        for split in self.splits:\n            label_df = data_dictionary[f\"{split}_labels\"]\n            self.assert_valid_class_names(label_df[target_column_name], class_names)\n            label_df[target_column_name] = [\n                self.class_name_to_index[x] for x in label_df[target_column_name]\n            ]\n\n    @staticmethod\n    def assert_valid_class_names(target_column: pd.Series, class_names: list[str]):\n        non_defined_labels = set(target_column) - set(class_names)\n        if len(non_defined_labels) != 0:\n            raise OperationalException(\n                f\"Found non defined labels: {non_defined_labels}, \",\n                f\"expecting labels: {class_names}\",\n            )\n\n    def decode_class_names(self, class_ints: torch.Tensor) -> list[str]:\n        \"\"\"\n        decode class name, int -> str\n        \"\"\"\n\n        return [self.index_to_class_name[x.item()] for x in class_ints]\n\n    def init_class_names_to_index_mapping(self, class_names):\n        self.class_name_to_index = {s: i for i, s in enumerate(class_names)}\n        self.index_to_class_name = {i: s for i, s in enumerate(class_names)}\n        logger.info(f\"encoded class name to index: {self.class_name_to_index}\")\n\n    def convert_label_column_to_int(\n        self,","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/freqtrade/freqtrade/blob/1c8edfe4d1e8d11bd4b40e8fc3237c26c3a60e15/freqtrade/freqai/base_models/BasePyTorchClassifier.py#L107-L143","documentation":"Before encoding labels to integers, assert_valid_class_names computes the set difference between the values actually present in the target column and the declared class_names. Any label value not in class_names causes an OperationalException (note: the raise passes two strings, so Python joins them into a tuple message). It guards the index mapping self.class_name_to_index[x] from KeyError later.","triggerScenarios":"convert_label_column_to_int -> encode_class_names -> assert_valid_class_names finds a training label the user did not declare, e.g. class_names = ['down', 'up'] but the target column also contains 0 or 'neutral', or targets are numeric while class_names are strings, or NaNs survive into the label column.","commonSituations":"Target engineering produces a third state (e.g. flat/neutral) the config class_names omits; mixing int targets with str class names; renaming label values in feature engineering without updating class_names; NaN labels from insufficient lookahead.","solutions":["Make class_names cover every value the target column can take (e.g. ['down', 'neutral', 'up'] if the strategy can emit a neutral class).","Ensure target dtype matches class_names exactly (all strings or all ints, no mixed 0/1 with 'down'/'up').","Drop or fill NaN target rows in set_freqai_targets so no NaN reaches the classifier.","Re-train after the fix; the check runs at training time, so prediction-time surprises are prevented."],"exampleFix":"# before\nclass_names = ['down', 'up']\ndataframe['&-action'] = np.where(dataframe['ret'] < -0.01, 'down',\n                        np.where(dataframe['ret'] > 0.01, 'up', 'neutral'))  # 'neutral' undeclared\n\n# after\nclass_names = ['down', 'neutral', 'up']\nself.freqai.class_names = class_names","handlingStrategy":"validation","validationCode":"non_defined = set(df[target].dropna().unique()) - set(class_names)\nassert not non_defined, f\"Labels {non_defined} not in declared class_names {class_names}\"","typeGuard":"def labels_within_classes(target: 'pd.Series', class_names: list) -> bool:\n    return set(target.dropna().unique()).issubset(set(class_names))","tryCatchPattern":null,"preventionTips":["Derive class_names from the target-generating code in one place so vocabulary and declaration cannot drift.","Drop NaN target rows and keep dtypes consistent (all str or all int) between the target column and class_names."],"tags":["freqai","classification","labels","data-validation"],"backgroundTag":null,"analyzedSha":"1c8edfe4d1e8d11bd4b40e8fc3237c26c3a60e15","analyzedAt":"2026-08-15T05:09:08.096Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}