open-mmlab/mmdetection · error · TypeError

Output of `cast_data` should be a dict or a tuple with input

Error message

Output of `cast_data` should be a dict or a tuple with inputs and data_samples, but got{type(data)}: {data}

What it means

DetDataPreprocessor._get_pad_shape expects data produced by cast_data to be either a dict (with 'inputs') or a tuple/list of (inputs, data_samples). Any other structure raises TypeError because the pad shape cannot be derived.

Source

Thrown at mmdet/models/data_preprocessors/data_preprocessor.py:180

                pad_w = int(
                    np.ceil(ori_input.shape[2] /
                            self.pad_size_divisor)) * self.pad_size_divisor
                batch_pad_shape.append((pad_h, pad_w))
        # Process data with `default_collate`.
        elif isinstance(_batch_inputs, torch.Tensor):
            assert _batch_inputs.dim() == 4, (
                'The input of `ImgDataPreprocessor` should be a NCHW tensor '
                'or a list of tensor, but got a tensor with shape: '
                f'{_batch_inputs.shape}')
            pad_h = int(
                np.ceil(_batch_inputs.shape[2] /
                        self.pad_size_divisor)) * self.pad_size_divisor
            pad_w = int(
                np.ceil(_batch_inputs.shape[3] /
                        self.pad_size_divisor)) * self.pad_size_divisor
            batch_pad_shape = [(pad_h, pad_w)] * _batch_inputs.shape[0]
        else:
            raise TypeError('Output of `cast_data` should be a dict '
                            'or a tuple with inputs and data_samples, but got'
                            f'{type(data)}: {data}')
        return batch_pad_shape

    def pad_gt_masks(self,
                     batch_data_samples: Sequence[DetDataSample]) -> None:
        """Pad gt_masks to shape of batch_input_shape."""
        if 'masks' in batch_data_samples[0].gt_instances:
            for data_samples in batch_data_samples:
                masks = data_samples.gt_instances.masks
                data_samples.gt_instances.masks = masks.pad(
                    data_samples.batch_input_shape,
                    pad_val=self.mask_pad_value)

    def pad_gt_sem_seg(self,
                       batch_data_samples: Sequence[DetDataSample]) -> None:
        """Pad gt_sem_seg to shape of batch_input_shape."""
        if 'gt_sem_seg' in batch_data_samples[0]:

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Ensure data comes from the mmdet dataloader/collate_data (dict with 'inputs' and 'data_samples')
  2. If building batches manually, use the structure {'inputs': Tensor, 'data_samples': list[DetDataSample]}
  3. Call cast_data (usually done in forward) before _get_pad_shape via test_pad_shape/forward

Example fix

// before
data = [img_tensor1, img_tensor2]  # raw list
out = preprocessor(data)
// after
from mmdet.structures import DetDataSample
data = dict(inputs=torch.stack([img1, img2]), data_samples=[DetDataSample(), DetDataSample()])
out = preprocessor(data, training=False)
Defensive patterns

Strategy: type-guard

Validate before calling

assert isinstance(data, dict) and 'inputs' in data or (isinstance(data, (tuple, list)) and len(data) == 2)

Type guard

def is_valid_batch(data) -> bool:\n    return (isinstance(data, dict) and 'inputs' in data) or (isinstance(data, (tuple, list)) and len(data) == 2)

Try / catch

try:\n    out = preprocessor(data, training=False)\nexcept TypeError as e:\n    raise ValueError(f'Bad batch structure for preprocessor: {type(data)}') from e

Prevention

When it happens

Trigger: Calling data_preprocessor.forward(data) with a raw list of tensors, a single Tensor, or a custom collate output that is not a dict/tuple; test_step/forward with a non-standard data structure.

Common situations: Custom dataloaders whose collate_fn returns lists of samples instead of the mmdet structure; wrapping the preprocessor with third-party code that reshapes batches; feeding non-collated data during debugging.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/b1842e24dc003963. Report an issue: GitHub.