keras-team/keras · error · ValueError

Invalid subset name: {subset};expected "training" or "valida

Error message

Invalid subset name: {subset};expected "training" or "validation"

What it means

When ImageDataGenerator is created with validation_split, flow methods accept a subset argument restricted to 'training' or 'validation'; anything else raises this ValueError. The two strings select the post-split and pre-split fractions of the data.

Source

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

            else:
                self.image_shape = (3,) + self.target_size
        else:
            if self.data_format == "channels_last":
                self.image_shape = self.target_size + (1,)
            else:
                self.image_shape = (1,) + self.target_size
        self.save_to_dir = save_to_dir
        self.save_prefix = save_prefix
        self.save_format = save_format
        self.interpolation = interpolation
        if subset is not None:
            validation_split = self.image_data_generator._validation_split
            if subset == "validation":
                split = (0, validation_split)
            elif subset == "training":
                split = (validation_split, 1)
            else:
                raise ValueError(
                    f"Invalid subset name: {subset};"
                    'expected "training" or "validation"'
                )
        else:
            split = None
        self.split = split
        self.subset = subset

    def _get_batches_of_transformed_samples(self, index_array):
        """Gets a batch of transformed samples.

        Args:
            index_array: Array of sample indices to include in batch.
        Returns:
            A batch of transformed samples.
        """
        batch_x = np.zeros(
            (len(index_array),) + self.image_shape, dtype=self.dtype

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Use subset='training' or subset='validation' exactly (lowercase, full words)
  2. Check that ImageDataGenerator(validation_split=0.2) is set - subset is only meaningful with it
  3. Map config abbreviations: 'train'->'training', 'val'->'validation' before calling flow_*

Example fix

# before
train_it = gen.flow_from_directory(dir, subset='train')

# after
train_it = gen.flow_from_directory(dir, subset='training')
Defensive patterns

Strategy: validation

Validate before calling

assert subset in {'training', 'validation', None}, subset

Type guard

def is_subset(v) -> bool: return v in {'training', 'validation'}

Try / catch

try:
    it = gen.flow_from_directory(d, subset=subset)
except ValueError as e:
    if 'Invalid subset name' in str(e):
        subset = {'train': 'training', 'val': 'validation'}.get(subset, subset)
    else:
        raise

Prevention

When it happens

Trigger: flow_from_directory(..., subset='train') or subset='val', or any subset string other than the two exact accepted ones.

Common situations: Using the abbreviations 'train'/'val' common in other frameworks (PyTorch datasets, fastai), inconsistent strings across migrated scripts, typos from config files.

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/70e7f4f9ebecdc93. Report an issue: GitHub.