{"record":{"id":"70e7f4f9ebecdc93","repo":"keras-team/keras","slug":"invalid-subset-name-subset-expected-training","errorCode":null,"errorMessage":"Invalid subset name: {subset};expected \"training\" or \"validation\"","messagePattern":"Invalid subset name: (.+?);expected \"training\" or \"validation\"","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/legacy/preprocessing/image.py","lineNumber":293,"sourceCode":"            else:\n                self.image_shape = (3,) + self.target_size\n        else:\n            if self.data_format == \"channels_last\":\n                self.image_shape = self.target_size + (1,)\n            else:\n                self.image_shape = (1,) + self.target_size\n        self.save_to_dir = save_to_dir\n        self.save_prefix = save_prefix\n        self.save_format = save_format\n        self.interpolation = interpolation\n        if subset is not None:\n            validation_split = self.image_data_generator._validation_split\n            if subset == \"validation\":\n                split = (0, validation_split)\n            elif subset == \"training\":\n                split = (validation_split, 1)\n            else:\n                raise ValueError(\n                    f\"Invalid subset name: {subset};\"\n                    'expected \"training\" or \"validation\"'\n                )\n        else:\n            split = None\n        self.split = split\n        self.subset = subset\n\n    def _get_batches_of_transformed_samples(self, index_array):\n        \"\"\"Gets a batch of transformed samples.\n\n        Args:\n            index_array: Array of sample indices to include in batch.\n        Returns:\n            A batch of transformed samples.\n        \"\"\"\n        batch_x = np.zeros(\n            (len(index_array),) + self.image_shape, dtype=self.dtype","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/legacy/preprocessing/image.py#L275-L311","documentation":"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.","triggerScenarios":"flow_from_directory(..., subset='train') or subset='val', or any subset string other than the two exact accepted ones.","commonSituations":"Using the abbreviations 'train'/'val' common in other frameworks (PyTorch datasets, fastai), inconsistent strings across migrated scripts, typos from config files.","solutions":["Use subset='training' or subset='validation' exactly (lowercase, full words)","Check that ImageDataGenerator(validation_split=0.2) is set - subset is only meaningful with it","Map config abbreviations: 'train'->'training', 'val'->'validation' before calling flow_*"],"exampleFix":"# before\ntrain_it = gen.flow_from_directory(dir, subset='train')\n\n# after\ntrain_it = gen.flow_from_directory(dir, subset='training')","handlingStrategy":"validation","validationCode":"assert subset in {'training', 'validation', None}, subset","typeGuard":"def is_subset(v) -> bool: return v in {'training', 'validation'}","tryCatchPattern":"try:\n    it = gen.flow_from_directory(d, subset=subset)\nexcept ValueError as e:\n    if 'Invalid subset name' in str(e):\n        subset = {'train': 'training', 'val': 'validation'}.get(subset, subset)\n    else:\n        raise","preventionTips":["Expand abbreviations in config loaders: train->training, val->validation","Only pass subset when validation_split is set on the generator"],"tags":["keras","image-data-generator","subset","invalid-argument"],"backgroundTag":"invalid-enum-value","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}