roboflow/supervision · error · ValueError
Expected 'names' to be a list or dict in data.yaml at '{file
Error message
Expected 'names' to be a list or dict in data.yaml at '{file_path}', got {type(names).__name__}. What it means
Raised by the YOLO data.yaml class-name loader when the 'names' entry is neither a list nor a dict (e.g. a plain string or a number). Ultralytics-style data.yaml must define names either as a list in class-index order or as a mapping of index/name; anything else cannot be mapped to ordered class names, so supervision raises with the actual type found.
Source
Thrown at src/supervision/dataset/formats/yolo.py:134
return False
int_like = [_is_int_like(k) for k in keys]
if any(int_like) and not all(int_like):
mixed_numeric = [k for k, il in zip(keys, int_like) if il][:3]
mixed_other = [k for k, il in zip(keys, int_like) if not il][:3]
raise ValueError(
f"Expected 'names' dict in data.yaml at '{file_path}' to have either "
f"all numeric or all non-numeric keys, got a mix: "
f"numeric {mixed_numeric} and non-numeric {mixed_other} keys."
)
if all(int_like):
sorted_keys = sorted(keys, key=lambda k: int(k))
else:
sorted_keys = sorted(keys, key=str)
return [str(names[key]) for key in sorted_keys]
if isinstance(names, list):
return [str(name) for name in names]
raise ValueError(
"Expected 'names' to be a list or dict in data.yaml at "
f"'{file_path}', got {type(names).__name__}."
)
def _image_name_to_annotation_name(image_name: str) -> str:
base_name, _ = os.path.splitext(image_name)
return base_name + ".txt"
def yolo_annotations_to_detections(
lines: list[str],
resolution_wh: tuple[int, int],
with_masks: bool,
is_obb: bool = False,
) -> Detections:
if len(lines) == 0:
return Detections.empty()View on GitHub (pinned to 7f254d9784)
Solutions
- Open the data.yaml at the path in the error and inspect the `names:` entry.
- Rewrite names as a list (order = class index): names: [person, car, dog]
- Or as an explicit index map: names: {0: person, 1: car, 2: dog}.
- Re-run DetectionDataset.from_yolo; if it still fails, validate the yaml loads as expected with PyYAML first.
Example fix
# before (data.yaml) names: person # after (data.yaml) names: - person - car
Defensive patterns
Strategy: type-guard
Validate before calling
import yaml
def load_names(data_yaml: str) -> list[str]:
"""Validate the names entry of a YOLO data.yaml before use."""
names = yaml.safe_load(open(data_yaml)).get('names')
assert isinstance(names, (list, dict)), type(names)
return list(names) if isinstance(names, list) else [names[k] for k in sorted(names)] Type guard
def is_valid_names(names: object) -> bool:
"""names must be a list or a dict to be usable as class names."""
return isinstance(names, (list, dict)) Try / catch
try:
dataset = sv.DetectionDataset.from_yolo(data_yaml_path='data.yaml')
except ValueError as e:
if "Expected 'names'" in str(e):
raise SystemExit(f'Fix data.yaml: {e}') from e
raise Prevention
- Use the list form names: [a, b] in data.yaml — least ambiguity.
- Validate yaml with a linter or PyYAML load before dataset operations.
- Copy data.yaml structure from a known-good Ultralytics dataset.
When it happens
Trigger: DetectionDataset.from_yolo(data_yaml_path=...) where the YAML contains e.g. `names: person` (single bare string), `names: 80`, `names: null`, or a nested structure instead of a list/dict.
Common situations: Typo in data.yaml (missing `-` bullet or braces); minimal hand-written yaml that gives a scalar class name; a YAML indentation mistake that turns a list into a string; using a non-Ultralytics yaml schema.
Related errors
- Expected mapping in data.yaml at '{file_path}', got {type(da
- Expected 'names' dict in data.yaml at '{file_path}' to have
- Detections must have class_id attribute.
- Detections class_id must be a subset of source_to_target_map
- Class {class_name} not found in target classes. source_class
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/48de6af832361a42.
Report an issue: GitHub.