{"record":{"id":"44f2b7738cc0fa0a","repo":"keras-team/keras","slug":"if-class-mode-y-col-column-values-must","errorCode":null,"errorMessage":"If class_mode=\"{}\", y_col=\"{}\" column values must be strings.","messagePattern":"If class_mode=\"(.+?)\", y_col=\"(.+?)\" column values must be strings\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"keras/src/legacy/preprocessing/image.py","lineNumber":818,"sourceCode":"                )\n            )\n        # check that y_col has several column names if class_mode is\n        # multi_output\n        if (self.class_mode == \"multi_output\") and not isinstance(y_col, list):\n            raise TypeError(\n                'If class_mode=\"{}\", y_col must be a list. Received {}.'.format(\n                    self.class_mode, type(y_col).__name__\n                )\n            )\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","sourceCodeStart":800,"sourceCodeEnd":836,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/legacy/preprocessing/image.py#L800-L836","documentation":"For class_mode='binary' or 'sparse', the y_col column values must all be strings because labels are mapped through class indices derived from string classes.","triggerScenarios":"flow_from_dataframe(class_mode='binary'/'sparse') with numeric labels (0/1 ints) in y_col.","commonSituations":"CSV with integer labels; assuming numeric labels are accepted like in flow().","solutions":["Cast labels to strings: df[y_col] = df[y_col].astype(str)","Or use class_mode='categorical'/'raw' with numeric labels","Keep exactly 2 distinct string classes for binary"],"exampleFix":"// before\ndf['label'] = df['label']  # 0/1 ints, class_mode='binary'\n// after\ndf['label'] = df['label'].astype(str)  # '0'/'1'\n","handlingStrategy":"validation","validationCode":"assert df[y_col].map(lambda v: isinstance(v, str)).all()","typeGuard":"def labels_are_str(col): return col.map(lambda v: isinstance(v, str)).all()","tryCatchPattern":"try: flow_from_dataframe(..., class_mode='binary')\nexcept TypeError as e: if 'must be strings' in str(e): df[y_col] = df[y_col].astype(str)","preventionTips":["Store labels as strings in CSVs for binary/sparse modes"],"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"}