huggingface/transformers · error · ValueError

Stage_names must be set for transformers backbones

Error message

Stage_names must be set for transformers backbones

What it means

Raised by BackboneConfigMixin.verify_out_features_out_indices when self.stage_names is None. Every transformers-style backbone (e.g. Swin, Beit, ViT hybrids) must define an ordered list of stage names; out_features/out_indices alignment (set_output_features_output_indices) indexes into stage_names, so a missing list makes the whole scheme unusable. It fires on the first verification pass, before any out_features logic.

Source

Thrown at src/transformers/backbone_utils.py:79

        out_features, out_indices = self._out_features, self._out_indices
        if out_indices is None and out_features is None:
            out_indices = [len(self.stage_names) - 1]
            out_features = [self.stage_names[-1]]
        elif out_indices is None and out_features is not None:
            out_indices = [self.stage_names.index(layer) for layer in out_features]
        elif out_features is None and out_indices is not None:
            out_features = [self.stage_names[idx] for idx in out_indices]

        # Update values and verify that the aligned out_features and out_indices are valid
        self._out_features, self._out_indices = out_features, out_indices
        self.verify_out_features_out_indices()

    def verify_out_features_out_indices(self):
        """
        Verify that out_indices and out_features are valid for the given stage_names.
        """
        if self.stage_names is None:
            raise ValueError("Stage_names must be set for transformers backbones")

        if self._out_features is not None:
            if not isinstance(self._out_features, (list,)):
                raise ValueError(f"out_features must be a list got {type(self._out_features)}")
            if any(feat not in self.stage_names for feat in self._out_features):
                raise ValueError(
                    f"out_features must be a subset of stage_names: {self.stage_names} got {self._out_features}"
                )
            if len(self._out_features) != len(set(self._out_features)):
                raise ValueError(f"out_features must not contain any duplicates, got {self._out_features}")
            if self._out_features != (
                sorted_feats := [feat for feat in self.stage_names if feat in self._out_features]
            ):
                raise ValueError(
                    f"out_features must be in the same order as stage_names, expected {sorted_feats} got {self._out_features}"
                )

        if self._out_indices is not None:

View on GitHub (pinned to a597f97485)

Solutions

  1. Define stage_names in the config class, e.g. self.stage_names = [f'stage{i}' for i in range(num_stages)] before calling set_output_features_output_indices
  2. If subclassing an existing backbone config, do not overwrite stage_names with None; reuse the parent's list or extend it
  3. When loading, pass stage_names explicitly if the checkpoint config predates the attribute: BackboneConfig.from_pretrained(..., stage_names=[...])

Example fix

// before
class MyBackboneConfig(BackboneConfigMixin):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # stage_names never set
        self.set_output_features_output_indices(None, None)
// after
class MyBackboneConfig(BackboneConfigMixin):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.stage_names = [f"stage{i}" for i in range(self.num_stages)]
        self.set_output_features_output_indices(None, None)
Defensive patterns

Strategy: validation

Validate before calling

cfg = MyBackboneConfig(...)
if getattr(cfg, "stage_names", None) is None:
    cfg.stage_names = [f"stage{i}" for i in range(cfg.num_stages)]
cfg.set_output_features_output_indices(out_features, out_indices)

Type guard

def has_stage_names(cfg) -> bool:
    names = getattr(cfg, "stage_names", None)
    return isinstance(names, (list, tuple)) and len(names) > 0 and all(isinstance(n, str) for n in names)

Try / catch

try:
    cfg.set_output_features_output_indices(out_features, out_indices)
except ValueError as e:
    if "Stage_names must be set" in str(e):
        raise TypeError("MyBackboneConfig must define stage_names before use") from e
    raise

Prevention

When it happens

Trigger: Instantiating a backbone config that inherits BackboneConfigMixin but never sets stage_names (custom/new backbone implementations); calling config.set_output_features_output_indices(...) on such a config; loading a checkpoint whose config class forgot stage_names in its __init__.

Common situations: Authors of new model backbones who copy the mixin but skip defining stage_names; subclasses that override __init__ without calling super or without populating stage_names; serialization edge cases where stage_names was dropped from the config dict.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/8b81897ac84cd5da. Report an issue: GitHub.