{"record":{"id":"ceb7e41a27dff77d","repo":"keras-team/keras","slug":"if-class-mode-y-col-column-values-must-ceb7e4","errorCode":null,"errorMessage":"If class_mode=\"{}\", y_col=\"{}\" column values must be type string, list or tuple.","messagePattern":"If class_mode=\"(.+?)\", y_col=\"(.+?)\" column values must be type string, list or tuple\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"keras/src/legacy/preprocessing/image.py","lineNumber":840,"sourceCode":"        # 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                )\n        # raise warning if classes are given but will be unused\n        if classes and self.class_mode in {\n            \"input\",\n            \"multi_output\",\n            \"raw\",\n            None,\n        }:\n            warnings.warn(\n                '`classes` will be ignored given the class_mode=\"{}\"'.format(\n                    self.class_mode\n                )\n            )\n        # check that if weight column that the values are numerical","sourceCodeStart":822,"sourceCodeEnd":858,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/legacy/preprocessing/image.py#L822-L858","documentation":"For class_mode='categorical', every value in y_col must be a string, list, or tuple (list/tuple = multi-label). Other types (ints, floats, NaN) are rejected.","triggerScenarios":"flow_from_dataframe(class_mode='categorical') with numeric labels or NaN in y_col.","commonSituations":"Numeric CSV labels; missing annotations read as NaN.","solutions":["Cast to string: df[y_col] = df[y_col].astype(str)","Drop NaN label rows: df.dropna(subset=[y_col])","For multi-label, store lists of strings per row"],"exampleFix":"// before\ndf['tags'] = df['tags']  # e.g. 1, 2, NaN\n// after\ndf['tags'] = df['tags'].astype(str)\ndf = df.dropna(subset=['tags']) if had_nan\n","handlingStrategy":"validation","validationCode":"ok = df[y_col].map(lambda v: isinstance(v, (str, list, tuple))).all()\nassert ok","typeGuard":"def cat_labels_ok(col): return col.map(lambda v: isinstance(v, (str, list, tuple))).all()","tryCatchPattern":"try: flow_from_dataframe(..., class_mode='categorical')\nexcept TypeError as e: if 'string, list or tuple' in str(e): df[y_col] = df[y_col].astype(str)","preventionTips":["Normalize label types before training scripts"],"tags":["keras","dataframe","type-validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}