keras-team/keras · error · ValueError

If class_mode="binary" there must be 2 classes. {} class/es

Error message

If class_mode="binary" there must be 2 classes. {} class/es were given.

What it means

With class_mode='binary' and an explicit classes list, that list must contain exactly 2 entries (binary classification).

Source

Thrown at keras/src/legacy/preprocessing/image.py:827

            )
        # check that filenames/filepaths column values are all strings
        if not all(df[x_col].apply(lambda x: isinstance(x, str))):
            raise TypeError(
                f"All values in column x_col={x_col} must be strings."
            )
        # check labels are string if class_mode is binary or sparse
        if self.class_mode in {"binary", "sparse"}:
            if not all(df[y_col].apply(lambda x: isinstance(x, str))):
                raise TypeError(
                    'If class_mode="{}", y_col="{}" column '
                    "values must be strings.".format(self.class_mode, y_col)
                )
        # check that if binary there are only 2 different classes
        if self.class_mode == "binary":
            if classes:
                classes = set(classes)
                if len(classes) != 2:
                    raise ValueError(
                        'If class_mode="binary" there must be 2 '
                        "classes. {} class/es were given.".format(len(classes))
                    )
            elif df[y_col].nunique() != 2:
                raise ValueError(
                    'If class_mode="binary" there must be 2 classes. '
                    "Found {} classes.".format(df[y_col].nunique())
                )
        # check values are string, list or tuple if class_mode is categorical
        if self.class_mode == "categorical":
            types = (str, list, tuple)
            if not all(df[y_col].apply(lambda x: isinstance(x, types))):
                raise TypeError(
                    'If class_mode="{}", y_col="{}" column '
                    "values must be type string, list or tuple.".format(
                        self.class_mode, y_col
                    )
                )

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Trim classes to the 2 relevant labels
  2. Or switch to class_mode='categorical' for >2 classes
  3. Omit classes to let it infer from the column (must then have nunique()==2)

Example fix

// before
classes=['cat','dog','bird']; class_mode='binary'
// after
df2 = df[df.label.isin(['cat','dog'])]
classes=['cat','dog']  # or class_mode='categorical'
Defensive patterns

Strategy: validation

Validate before calling

assert classes is None or len(set(classes)) == 2

Type guard

def exactly_two(c): return c is None or len(set(c)) == 2

Try / catch

try: flow_from_dataframe(..., classes=classes)
except ValueError as e: if 'must be 2 classes' in str(e): classes = classes[:2]

Prevention

When it happens

Trigger: flow_from_dataframe(class_mode='binary', classes=['a','b','c']) or classes=['a'].

Common situations: Reusing a multi-class class list with a binary model; passing all dataset classes when only two were intended.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/be4d91cd0eccdf50. Report an issue: GitHub.