keras-team/keras · error · ValueError

If class_mode="binary" there must be 2 classes. Found {} cla

Error message

If class_mode="binary" there must be 2 classes. Found {} classes.

What it means

With class_mode='binary' and no classes argument, the y_col column must contain exactly 2 unique values. This variant reports the count found in the DataFrame.

Source

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

            )
        # 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
                    )
                )
        # raise warning if classes are given but will be unused
        if classes and self.class_mode in {
            "input",
            "multi_output",
            "raw",

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Filter rows so exactly 2 labels remain
  2. Pass classes=[pos,neg] explicitly to pin the two labels
  3. Switch to class_mode='categorical' for multi-class

Example fix

// before
gen.flow_from_dataframe(df, x_col='f', y_col='label', class_mode='binary')  # 3 labels
// after
df = df[df.label.isin(['cat','dog'])]
gen.flow_from_dataframe(df, x_col='f', y_col='label', class_mode='binary')
Defensive patterns

Strategy: validation

Validate before calling

assert df[y_col].nunique() == 2

Try / catch

try: flow_from_dataframe(..., class_mode='binary')
except ValueError as e: if 'Found' in str(e) and 'classes' in str(e): raise SystemExit('fix labels')

Prevention

When it happens

Trigger: flow_from_dataframe(class_mode='binary') where df[y_col].nunique() != 2 (e.g. 3 classes, or 1 after filtering).

Common situations: Filtering the DataFrame leaves 1 class; exploratory dataset actually has 3+ labels.

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/6de1fb52879de6b9. Report an issue: GitHub.