keras-team/keras · error · ValueError

Invalid color mode: {color_mode}; expected "rgb", "rgba", or

Error message

Invalid color mode: {color_mode}; expected "rgb", "rgba", or "grayscale".

What it means

Iterator.set_processing_attrs validates color_mode when constructing an image data iterator; only 'rgb', 'rgba', and 'grayscale' map to known channel counts (3, 4, 1). Any other string raises this ValueError because downstream code branches on color_mode to build the target tensor shape.

Source

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

            save_format: Format to use for saving sample images
                (if `save_to_dir` is set).
            subset: Subset of data (`"training"` or `"validation"`) if
                validation_split is set in ImageDataGenerator.
            interpolation: Interpolation method used to resample the image if
                the target size is different from that of the loaded image.
                Supported methods are "nearest", "bilinear", and "bicubic". If
                PIL version 1.1.3 or newer is installed, "lanczos" is also
                supported. If PIL version 3.4.0 or newer is installed, "box" and
                "hamming" are also supported. By default, "nearest" is used.
            keep_aspect_ratio: Boolean, whether to resize images to a target
                size without aspect ratio distortion. The image is cropped in
                the center with target aspect ratio before resizing.
        """
        self.image_data_generator = image_data_generator
        self.target_size = tuple(target_size)
        self.keep_aspect_ratio = keep_aspect_ratio
        if color_mode not in {"rgb", "rgba", "grayscale"}:
            raise ValueError(
                f"Invalid color mode: {color_mode}"
                '; expected "rgb", "rgba", or "grayscale".'
            )
        self.color_mode = color_mode
        self.data_format = data_format
        if self.color_mode == "rgba":
            if self.data_format == "channels_last":
                self.image_shape = self.target_size + (4,)
            else:
                self.image_shape = (4,) + self.target_size
        elif self.color_mode == "rgb":
            if self.data_format == "channels_last":
                self.image_shape = self.target_size + (3,)
            else:
                self.image_shape = (3,) + self.target_size
        else:
            if self.data_format == "channels_last":
                self.image_shape = self.target_size + (1,)

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Use exactly 'grayscale', 'rgb', or 'rgba' in lowercase
  2. For single-channel images use 'grayscale', not 'L', 'gray', or 'greyscale'
  3. Sanitize user-supplied config values with .lower() and a whitelist before passing them in

Example fix

# before
it = train_gen.flow_from_directory(dir, color_mode='greyscale')

# after
it = train_gen.flow_from_directory(dir, color_mode='grayscale')
Defensive patterns

Strategy: validation

Validate before calling

assert color_mode in {'rgb', 'rgba', 'grayscale'}, f'bad color_mode: {color_mode}'

Type guard

def is_color_mode(v) -> bool: return v in {'rgb', 'rgba', 'grayscale'}

Try / catch

try:
    it = gen.flow_from_directory(d, color_mode=color_mode)
except ValueError as e:
    if 'Invalid color mode' in str(e):
        color_mode = color_mode.lower().replace('greyscale', 'grayscale')
    else:
        raise

Prevention

When it happens

Trigger: flow_from_directory(..., color_mode='greyscale') (British spelling), color_mode='gray', color_mode='RGB' (uppercase), or a typo like 'rgp'.

Common situations: British vs American spelling confusion ('greyscale'), copy-pasting config from PIL/OpenCV code that uses mode strings like 'L', porting tutorials between library versions.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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