{"record":{"id":"4263661a99535d0f","repo":"keras-team/keras","slug":"invalid-subset-name-subset-expected-training-426366","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":581,"sourceCode":"            x_misc = []\n\n        if y is not None and len(x) != len(y):\n            raise ValueError(\n                \"`x` (images tensor) and `y` (labels) \"\n                \"should have the same length. \"\n                f\"Found: x.shape = {np.asarray(x).shape}, \"\n                f\"y.shape = {np.asarray(y).shape}\"\n            )\n        if sample_weight is not None and len(x) != len(sample_weight):\n            raise ValueError(\n                \"`x` (images tensor) and `sample_weight` \"\n                \"should have the same length. \"\n                f\"Found: x.shape = {np.asarray(x).shape}, \"\n                f\"sample_weight.shape = {np.asarray(sample_weight).shape}\"\n            )\n        if subset is not None:\n            if subset not in {\"training\", \"validation\"}:\n                raise ValueError(\n                    f\"Invalid subset name: {subset}\"\n                    '; expected \"training\" or \"validation\".'\n                )\n            split_idx = int(len(x) * image_data_generator._validation_split)\n\n            if (\n                y is not None\n                and not ignore_class_split\n                and not np.array_equal(\n                    np.unique(y[:split_idx]), np.unique(y[split_idx:])\n                )\n            ):\n                raise ValueError(\n                    \"Training and validation subsets \"\n                    \"have different number of classes after \"\n                    \"the split. If your numpy arrays are \"\n                    \"sorted by the label, you might want \"\n                    \"to shuffle them.\"","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/legacy/preprocessing/image.py#L563-L599","documentation":"ImageDataGenerator splits data via subset='training'/'validation' only. NumpyArrayIterator rejects any other subset string.","triggerScenarios":"Calling gen.flow(x, y, subset='train'), subset='val', or subset='test' (also requires validation_split set on the generator).","commonSituations":"Copying tutorial code and renaming subsets; using subset without validation_split; Keras 2 vs 3 naming confusion.","solutions":["Use subset='training' or subset='validation' exactly","Pass validation_split=0.2 (0<split<1) to ImageDataGenerator when using subsets"],"exampleFix":"// before\ngen.flow(x, y, subset='train')\n// after\ngen = ImageDataGenerator(validation_split=0.2)\ngen.flow(x, y, subset='training')\n","handlingStrategy":"validation","validationCode":"assert subset in (None, 'training', 'validation')","typeGuard":"def is_valid_subset(s): return s is None or s in {'training','validation'}","tryCatchPattern":"try: gen.flow(x, y, subset=s)\nexcept ValueError as e: if 'Invalid subset' in str(e): s = 'training'","preventionTips":["Centralize subset strings as constants","Require validation_split when subsets are used"],"tags":["keras","validation-split","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}