open-mmlab/mmdetection · error · TypeError

The type of frame_range must be int or list.

Error message

The type of frame_range must be int or list.

What it means

This transform (BaseFrameSample in mmdet's frame_sampling) accepts frame_range as either an int (interpreted symmetrically) or a list of exactly 2 ints [left, right] with left <= 0 <= right. Any other type — a string from a config, a tuple, a single-element list, or None — raises TypeError in __init__.

Source

Thrown at mmdet/datasets/transforms/frame_sampling.py:109

    """

    def __init__(self,
                 num_ref_imgs: int = 1,
                 frame_range: Union[int, List[int]] = 10,
                 filter_key_img: bool = True,
                 collect_video_keys: List[str] = ['video_id', 'video_length']):
        self.num_ref_imgs = num_ref_imgs
        self.filter_key_img = filter_key_img
        if isinstance(frame_range, int):
            assert frame_range >= 0, 'frame_range can not be a negative value.'
            frame_range = [-frame_range, frame_range]
        elif isinstance(frame_range, list):
            assert len(frame_range) == 2, 'The length must be 2.'
            assert frame_range[0] <= 0 and frame_range[1] >= 0
            for i in frame_range:
                assert isinstance(i, int), 'Each element must be int.'
        else:
            raise TypeError('The type of frame_range must be int or list.')
        self.frame_range = frame_range
        super().__init__(collect_video_keys=collect_video_keys)

    def sampling_frames(self, video_length: int, key_frame_id: int):
        """Sampling frames.

        Args:
            video_length (int): The length of the video.
            key_frame_id (int): The key frame id.

        Returns:
            list[int]: The sampled frame indices.
        """
        if video_length > 1:
            left = max(0, key_frame_id + self.frame_range[0])
            right = min(key_frame_id + self.frame_range[1], video_length - 1)
            frame_ids = list(range(0, video_length))

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Use an int: frame_range=2, or a two-element list: frame_range=[-2, 2]
  2. If the value comes from CLI/env/config file, cast it: frame_range=int(frame_range) or [int(v) for v in frame_range]
  3. Remember the sign convention: first element <= 0, second >= 0 (offsets relative to the key frame)

Example fix

# before
frame_sample = dict(type='FrameSampler', frame_range='[-2, 2]')
# after
frame_sample = dict(type='FrameSampler', frame_range=[-2, 2])
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(frame_range, str):
    frame_range = eval(frame_range) if frame_range.startswith('[') else int(frame_range)
assert isinstance(frame_range, (int, list))

Type guard

def is_valid_frame_range(fr) -> bool:
    if isinstance(fr, int):
        return True
    return (isinstance(fr, list) and len(fr) == 2
            and all(isinstance(i, int) for i in fr)
            and fr[0] <= 0 <= fr[1])

Prevention

When it happens

Trigger: Configuring a frame sampling transform with frame_range='3' (string), (1, 3) (tuple), 2.0 (float), or [1] (wrong-length list). Note the list-element assertions are separate; this specific raise is only for non-int non-list types.

Common situations: YAML/JSON config templating that renders numbers as strings; porting configs from other codebases that use tuples; forgetting that frame_range must be a plain int or list when writing custom video training configs.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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