huggingface/transformers · error · ValueError
out_features must be a list got {type(self._out_features)}
Error message
out_features must be a list got {type(self._out_features)} What it means
Raised by BackboneConfigMixin.verify_out_features_out_indices when self._out_features is not None but fails isinstance(self._out_features, list). Only Python lists are accepted (note: unlike out_indices, a tuple is NOT normalized here — set_output_features_output_indices only converts out_indices tuples to lists), because downstream code assumes list ordering/mutation semantics.
Source
Thrown at src/transformers/backbone_utils.py:83
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:
if not isinstance(self._out_indices, list):
raise ValueError(f"out_indices must be a list, got {type(self._out_indices)}")
# Convert negative indices to their positive equivalent: [-1,] -> [len(stage_names) - 1,]
positive_indices = tuple(idx % len(self.stage_names) if idx < 0 else idx for idx in self._out_indices)View on GitHub (pinned to a597f97485)
Solutions
- Wrap the value in a list: out_features=["stage1", "stage3"]
- Normalize before constructing the config: out_features = list(out_features) if isinstance(out_features, (tuple, list)) else [out_features]
- Fix config parsers that emit strings; split "stage1,stage2" into a list of names
Example fix
// before
cfg = SwinBackboneConfig(out_features=("stage1", "stage3")) # tuple rejected
// after
cfg = SwinBackboneConfig(out_features=["stage1", "stage3"]) Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(out_features, list):
out_features = list(out_features) if isinstance(out_features, (tuple, set)) else [out_features]
cfg = SomeBackboneConfig(out_features=out_features) Type guard
def is_valid_out_features(out_features) -> bool:
return out_features is None or (
isinstance(out_features, list) and all(isinstance(f, str) for f in out_features)
) Try / catch
try:
cfg = SomeBackboneConfig(out_features=out_features)
except ValueError as e:
if "out_features must be a list" in str(e):
cfg = SomeBackboneConfig(out_features=list(out_features))
else:
raise Prevention
- Always pass out_features as a Python list of strings
- Unlike out_indices, tuples are NOT normalized for out_features
- Split comma-separated strings from CLI/JSON into lists before constructing the config
When it happens
Trigger: Passing out_features as a tuple, string, numpy array, or comma-separated value like "stage1,stage2" to a backbone config; e.g. SwinBackboneConfig(out_features=("stage1", "stage3")) or out_features="stage2".
Common situations: Configs loaded from YAML/JSON where a single-element list degenerated into a plain string; users writing tuples for immutability; CLI arg parsing that yields a string instead of a list.
Related errors
- Stage_names must be set for transformers backbones
- out_features must be a subset of stage_names: {self.stage_na
- out_features must not contain any duplicates, got {self._out
- out_features must be in the same order as stage_names, expec
- out_indices must be a list, got {type(self._out_indices)}
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/6fe077879319813a.
Report an issue: GitHub.