ultralytics/yolov5 · error · ValueError

Invalid 'names' field in dataset yaml file. Please use a lis

Error message

Invalid 'names' field in dataset yaml file. Please use a list or dictionary

What it means

Raised while restoring a dataset config from a Comet.ml artifact in the Comet logger's resume/download path. The artifact's stored metadata must contain a 'names' field that is either a dict (class-index -> name) or a list of class names; anything else (None, a string, a number) is rejected. This mirrors YOLOv5's requirement that dataset YAML 'names' be a list or dict so it can be normalized to {int: str}.

Source

Thrown at utils/loggers/comet/__init__.py:383

        self.experiment.log_artifact(artifact)

    def download_dataset_artifact(self, artifact_path):
        """Downloads a dataset artifact to a specified directory using the experiment's logged artifact."""
        logged_artifact = self.experiment.get_artifact(artifact_path)
        artifact_save_dir = str(Path(self.opt.save_dir) / logged_artifact.name)
        logged_artifact.download(artifact_save_dir)

        metadata = logged_artifact.metadata
        data_dict = metadata.copy()
        data_dict["path"] = artifact_save_dir

        metadata_names = metadata.get("names")
        if isinstance(metadata_names, dict):
            data_dict["names"] = {int(k): v for k, v in metadata.get("names").items()}
        elif isinstance(metadata_names, list):
            data_dict["names"] = {int(k): v for k, v in zip(range(len(metadata_names)), metadata_names)}
        else:
            raise ValueError("Invalid 'names' field in dataset yaml file. Please use a list or dictionary")  # noqa: TRY004

        return self.update_data_paths(data_dict)

    def update_data_paths(self, data_dict):
        """Updates data paths in the dataset dictionary, defaulting 'path' to an empty string if not present."""
        path = data_dict.get("path", "")

        for split in ["train", "val", "test"]:
            if data_dict.get(split):
                split_path = data_dict.get(split)
                data_dict[split] = (
                    f"{path}/{split_path}" if isinstance(split_path, str) else [f"{path}/{x}" for x in split_path]
                )

        return data_dict

    def on_pretrain_routine_end(self, paths):
        """Called at the end of pretraining routine to handle paths if training is not being resumed."""

View on GitHub (pinned to 20d1d78a08)

Solutions

  1. Inspect the artifact metadata (logged_artifact.metadata) and fix the 'names' entry to a list like ['person', 'car'] or a dict like {0: 'person', 1: 'car'}, then re-upload the artifact.
  2. If the source dataset YAML has a malformed 'names' field, correct it there and re-log the artifact from a fresh training run.
  3. If you don't need artifact-based dataset restore, bypass this path: point --data directly at your local dataset YAML instead of resuming the Comet artifact.
  4. As a last resort, patch the metadata before download: overwrite data_dict['names'] with a valid dict of length nc before calling update_data_paths.

Example fix

# before (artifact metadata): metadata = {"names": "person,car", "nc": 2}
# after
metadata = {"names": ["person", "car"], "nc": 2}
# or equivalently
metadata = {"names": {0: "person", 1: "car"}, "nc": 2}
Defensive patterns

Strategy: validation

Validate before calling

names = artifact_metadata.get("names")
if not isinstance(names, (dict, list)) or len(names) == 0:
    raise ValueError(
        f"Comet artifact metadata 'names' must be a non-empty list or dict, got {type(names).__name__}; "
        "fix the artifact metadata or point --data at a local dataset YAML"
    )

Type guard

def is_valid_names_field(names) -> bool:
    """True when 'names' can be normalized to {int: str}."""
    if isinstance(names, dict):
        return all(isinstance(k, (int, str)) and str(k).lstrip("-").isdigit() for k in names)
    if isinstance(names, list):
        return all(isinstance(v, str) for v in names)
    return False

Try / catch

try:
    data_dict = comet_logger.restore_dataset_from_artifact(...)  # or the download path
except ValueError as e:
    if "Invalid 'names' field" in str(e):
        LOGGER.warning("Comet artifact metadata malformed; falling back to local --data YAML")
        data_dict = yaml_load(local_data_yaml)
    else:
        raise

Prevention

When it happens

Trigger: Calling the Comet dataset-restore path (e.g. resuming a run whose data was logged as a Comet artifact, or downloading an experiment's dataset artifact via this logger) where the artifact metadata's 'names' key is missing (metadata.get('names') returns None) or is not a dict/list (e.g. a plain string like 'person' or an int nc).

Common situations: The dataset YAML uploaded with the Comet artifact had a malformed 'names' field (a string, or omitted entirely); the artifact was created manually or by an older/newer YOLOv5 version whose metadata schema differs; Comet metadata was stripped or altered when the artifact was versioned; a custom names format (e.g. comma-separated string) was used.

Related errors


AI-assisted analysis of ultralytics/yolov5@20d1d78a08 (2026-08-15). Data as JSON: /api/errors/228def2283ba5d1a. Report an issue: GitHub.