{"record":{"id":"be4d91cd0eccdf50","repo":"keras-team/keras","slug":"if-class-mode-binary-there-must-be-2-classes","errorCode":null,"errorMessage":"If class_mode=\"binary\" there must be 2 classes. {} class/es were given.","messagePattern":"If class_mode=\"binary\" there must be 2 classes\\. (.+?) class/es were given\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/legacy/preprocessing/image.py","lineNumber":827,"sourceCode":"            )\n        # check that filenames/filepaths column values are all strings\n        if not all(df[x_col].apply(lambda x: isinstance(x, str))):\n            raise TypeError(\n                f\"All values in column x_col={x_col} must be strings.\"\n            )\n        # check labels are string if class_mode is binary or sparse\n        if self.class_mode in {\"binary\", \"sparse\"}:\n            if not all(df[y_col].apply(lambda x: isinstance(x, str))):\n                raise TypeError(\n                    'If class_mode=\"{}\", y_col=\"{}\" column '\n                    \"values must be strings.\".format(self.class_mode, y_col)\n                )\n        # check that if binary there are only 2 different classes\n        if self.class_mode == \"binary\":\n            if classes:\n                classes = set(classes)\n                if len(classes) != 2:\n                    raise ValueError(\n                        'If class_mode=\"binary\" there must be 2 '\n                        \"classes. {} class/es were given.\".format(len(classes))\n                    )\n            elif df[y_col].nunique() != 2:\n                raise ValueError(\n                    'If class_mode=\"binary\" there must be 2 classes. '\n                    \"Found {} classes.\".format(df[y_col].nunique())\n                )\n        # check values are string, list or tuple if class_mode is categorical\n        if self.class_mode == \"categorical\":\n            types = (str, list, tuple)\n            if not all(df[y_col].apply(lambda x: isinstance(x, types))):\n                raise TypeError(\n                    'If class_mode=\"{}\", y_col=\"{}\" column '\n                    \"values must be type string, list or tuple.\".format(\n                        self.class_mode, y_col\n                    )\n                )","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/legacy/preprocessing/image.py#L809-L845","documentation":"With class_mode='binary' and an explicit classes list, that list must contain exactly 2 entries (binary classification).","triggerScenarios":"flow_from_dataframe(class_mode='binary', classes=['a','b','c']) or classes=['a'].","commonSituations":"Reusing a multi-class class list with a binary model; passing all dataset classes when only two were intended.","solutions":["Trim classes to the 2 relevant labels","Or switch to class_mode='categorical' for >2 classes","Omit classes to let it infer from the column (must then have nunique()==2)"],"exampleFix":"// before\nclasses=['cat','dog','bird']; class_mode='binary'\n// after\ndf2 = df[df.label.isin(['cat','dog'])]\nclasses=['cat','dog']  # or class_mode='categorical'\n","handlingStrategy":"validation","validationCode":"assert classes is None or len(set(classes)) == 2","typeGuard":"def exactly_two(c): return c is None or len(set(c)) == 2","tryCatchPattern":"try: flow_from_dataframe(..., classes=classes)\nexcept ValueError as e: if 'must be 2 classes' in str(e): classes = classes[:2]","preventionTips":["Validate class lists against the binary model head before training"],"tags":["keras","binary-classification","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}