keras-team/keras · error · TypeError

If class_mode="{}", y_col="{}" column values must be type st

Error message

If class_mode="{}", y_col="{}" column values must be type string, list or tuple.

What it means

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.

Source

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

        # 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",
            None,
        }:
            warnings.warn(
                '`classes` will be ignored given the class_mode="{}"'.format(
                    self.class_mode
                )
            )
        # check that if weight column that the values are numerical

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Cast to string: df[y_col] = df[y_col].astype(str)
  2. Drop NaN label rows: df.dropna(subset=[y_col])
  3. For multi-label, store lists of strings per row

Example fix

// before
df['tags'] = df['tags']  # e.g. 1, 2, NaN
// after
df['tags'] = df['tags'].astype(str)
df = df.dropna(subset=['tags']) if had_nan
Defensive patterns

Strategy: validation

Validate before calling

ok = df[y_col].map(lambda v: isinstance(v, (str, list, tuple))).all()
assert ok

Type guard

def cat_labels_ok(col): return col.map(lambda v: isinstance(v, (str, list, tuple))).all()

Try / catch

try: flow_from_dataframe(..., class_mode='categorical')
except TypeError as e: if 'string, list or tuple' in str(e): df[y_col] = df[y_col].astype(str)

Prevention

When it happens

Trigger: flow_from_dataframe(class_mode='categorical') with numeric labels or NaN in y_col.

Common situations: Numeric CSV labels; missing annotations read as NaN.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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