{"record":{"id":"94b91f89727f2d8f","repo":"keras-team/keras","slug":"convnext-does-not-support-the-channels-first-ima","errorCode":null,"errorMessage":"ConvNeXt does not support the `channels_first` image data format. Switch to `channels_last` by editing your local config file at ~/.keras/keras.json","messagePattern":"ConvNeXt does not support the `channels_first` image data format\\. Switch to `channels_last` by editing your local config file at ~/\\.keras/keras\\.json","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/applications/convnext.py","lineNumber":395,"sourceCode":"                the 4D tensor output of the last convolutional layer.\n            - `avg` means that global average pooling will be applied\n                to the output of the last convolutional layer,\n                and thus the output of the model will be a 2D tensor.\n            - `max` means that global max pooling will be applied.\n        classes: optional number of classes to classify images into,\n            only to be specified if `include_top` is `True`,\n            and if no `weights` argument is specified.\n        classifier_activation: A `str` or callable.\n            The activation function to use\n            on the \"top\" layer. Ignored unless `include_top=True`.\n            Set `classifier_activation=None` to return the logits\n            of the \"top\" layer.\n\n    Returns:\n        A model instance.\n    \"\"\"\n    if backend.image_data_format() == \"channels_first\":\n        raise ValueError(\n            \"ConvNeXt does not support the `channels_first` image data \"\n            \"format. Switch to `channels_last` by editing your local \"\n            \"config file at ~/.keras/keras.json\"\n        )\n    if not (weights in {\"imagenet\", None} or file_utils.exists(weights)):\n        raise ValueError(\n            \"The `weights` argument should be either \"\n            \"`None` (random initialization), `imagenet` \"\n            \"(pre-training on ImageNet), \"\n            \"or the path to the weights file to be loaded.\"\n        )\n\n    if weights == \"imagenet\" and include_top and classes != 1000:\n        raise ValueError(\n            'If using `weights=\"imagenet\"` with `include_top=True`, '\n            \"`classes` should be 1000. \"\n            f\"Received classes={classes}\"\n        )","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/applications/convnext.py#L377-L413","documentation":"Internal guard in _extract_patches_2d: after the public wrapper normalized types, the 2D path requires an int or a length-2 tuple/list. A length-3 tuple reaching here means a 3D size was supplied to the 2D extractor (or extract_patches_2d was called directly), which cannot be interpreted.","triggerScenarios":"Calling the private/public 2D extractor with a 3-element size, e.g. extract_patches(images, size=(2, 2, 2)) on 4D images; invoking keras.src.ops.image.extract_patches_2d directly with a 3D patch spec; branching code that reuses one size variable for both 2D and 3D inputs.","commonSituations":"A pipeline that handles both MRI volumes and 2D slices with a single config-driven size; refactors where extract_patches was split into 2D/3D paths and the dispatch condition on image rank was inverted or removed.","solutions":["Use a 2-element size (or int) for 2D images; reserve length-3 tuples for volumes","Dispatch on image rank: ndim==4 -> size2d, ndim==5 -> size3d, instead of one shared size","Update stale calls to the private _extract_patches_2d that still pass 3D sizes from before a refactor"],"exampleFix":"before: extract_patches_2d(imgs, size=(4, 4, 4)) -> TypeError; after: extract_patches_2d(imgs, size=(4, 4))","handlingStrategy":"validation","validationCode":"if images.ndim == 4 and not (isinstance(size, int) or len(size) == 2):\n    size = size[:2]  # or raise: 2D path needs a 2-element size","typeGuard":"def is_2d_size(size) -> bool:\n    return isinstance(size, int) or (isinstance(size, (tuple, list)) and len(size) == 2)","tryCatchPattern":null,"preventionTips":["Dispatch 2D vs 3D on input rank and pick size accordingly","Do not call private _extract_patches_* helpers from user code","Keep one source of truth for patch size per modality"],"tags":["keras","image-ops","argument-validation","internal-api"],"backgroundTag":"invalid-argument-shape","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}