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
- Ensure data comes from the mmdet dataloader/collate_data (dict with 'inputs' and 'data_samples')
- If building batches manually, use the structure {'inputs': Tensor, 'data_samples': list[DetDataSample]}
- 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
- Always feed data from mmdet dataloaders
- Use dict(inputs=..., data_samples=...) when building batches manually
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
- The annotation file of Open Images Challenge should be a txt
- Invalid text mode "{self.text_mode}".
- No sample in split "{self.split}".
- sampler should be an instance of ``Sampler``, but got {sampl
- batch_size should be a positive integer value, but got batch
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/b1842e24dc003963.
Report an issue: GitHub.