open-mmlab/mmdetection · error · ValueError

Invalid flipping direction

Error message

Invalid flipping direction '{flip_direction}'

What it means

merge_aug_masks reverts test-time-augmentation flips on predicted masks and only understands 'horizontal', 'vertical', and 'diagonal' flip directions. When the augmentation config produced another direction string, it raises ValueError.

Solutions

  1. Use only 'horizontal', 'vertical', or 'diagonal' in flip_direction in the test-time aug pipeline
  2. Check custom Flip transforms to ensure they emit these exact lowercase strings

Example fix

# before
tta_pipeline=[..., dict(type='Flip', flip_direction='diag')]
# after
tta_pipeline=[..., dict(type='Flip', flip_direction='diagonal')]
Defensive patterns

Strategy: validation

Validate before calling

assert flip_direction in ('horizontal', 'vertical', 'diagonal'), flip_direction

Type guard

def is_valid_flip_direction(d: str) -> bool:
    return d in ('horizontal', 'vertical', 'diagonal')

Try / catch

try:
    merge_aug_masks(masks, cfg)
except ValueError as e:
    if 'Invalid flipping direction' in str(e):
        # normalize or drop unsupported flips
        ...
    raise

Prevention

When it happens

Trigger: Calling merge_aug_masks (via multi-scale / flip TTA predict) where aug_masks metadata carries a flip_direction other than the three supported values, e.g. 'diag' or a custom string set in the test pipeline.

Common situations: Custom flip transforms in the test pipeline, or configs migrated from other repos (mmdet3d uses 'DIAGONAL') where direction casing/values differ.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at mmdet/models/test_time_augs/merge_augs.py:212

    recovered_masks = []
    for i, mask in enumerate(aug_masks):
        if weights is not None:
            assert len(weights) == len(aug_masks)
            weight = weights[i]
        else:
            weight = 1
        flip = img_metas.get('flip', False)
        if flip:
            flip_direction = img_metas['flip_direction']
            if flip_direction == 'horizontal':
                mask = mask[:, :, :, ::-1]
            elif flip_direction == 'vertical':
                mask = mask[:, :, ::-1, :]
            elif flip_direction == 'diagonal':
                mask = mask[:, :, :, ::-1]
                mask = mask[:, :, ::-1, :]
            else:
                raise ValueError(
                    f"Invalid flipping direction '{flip_direction}'")
        recovered_masks.append(mask[None, :] * weight)

    merged_masks = torch.cat(recovered_masks, 0).mean(dim=0)
    if weights is not None:
        merged_masks = merged_masks * len(weights) / sum(weights)
    return merged_masks

View on GitHub (pinned to cfd5d3a985)