{"record":{"id":"68d45b6790867853","repo":"ultralytics/ultralytics","slug":"dataset-key-missing-either-names-or-nc-a","errorCode":null,"errorMessage":"{dataset} key missing ❌.\n either 'names' or 'nc' are required in all data YAMLs.","messagePattern":"(.+?) key missing ❌\\.\n either 'names' or 'nc' are required in all data YAMLs\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"critical","filePath":"ultralytics/data/utils.py","lineNumber":522,"sourceCode":"\n    # Read YAML\n    data = YAML.load(file, append_filename=True)  # dictionary\n\n    # Checks\n    for k in \"train\", \"val\":\n        if k not in data:\n            if k != \"val\" or \"validation\" not in data:\n                raise SyntaxError(\n                    emojis(f\"{dataset} '{k}:' key missing ❌.\\n'train' and 'val' are required in all data YAMLs.\")\n                )\n            LOGGER.warning(\"renaming data YAML 'validation' key to 'val' to match YOLO format.\")\n            data[\"val\"] = data.pop(\"validation\")  # replace 'validation' key with 'val' key\n    if split and not data.get(split):\n        raise FileNotFoundError(f\"{dataset} '{split}:' images not found ❌\")\n    # `names` compared to None, not membership: a bare `names:` parses to None and len(None) below\n    # raises. `nc` stays membership so a valueless `nc:` still reaches its \"must be an integer\" error.\n    if data.get(\"names\") is None and \"nc\" not in data:\n        raise SyntaxError(emojis(f\"{dataset} key missing ❌.\\n either 'names' or 'nc' are required in all data YAMLs.\"))\n    if \"nc\" in data and not isinstance(data[\"nc\"], int):\n        try:\n            nc = float(data[\"nc\"])  # accept integer-like values, e.g. '10' or 10.0, but not 1.9 or placeholders\n            if nc != int(nc):\n                raise ValueError\n            data[\"nc\"] = int(nc)\n        except (TypeError, ValueError):\n            raise SyntaxError(emojis(f\"{dataset} 'nc: {data['nc']}' must be an integer ❌.\"))\n    if data.get(\"names\") is not None and data.get(\"nc\") is not None and len(data[\"names\"]) != data[\"nc\"]:\n        raise SyntaxError(emojis(f\"{dataset} 'names' length {len(data['names'])} and 'nc: {data['nc']}' must match.\"))\n    if data.get(\"names\") is None:\n        data[\"names\"] = [f\"class_{i}\" for i in range(data[\"nc\"])]\n    else:\n        data[\"nc\"] = len(data[\"names\"])\n\n    data[\"names\"] = check_class_names(data[\"names\"])\n    data[\"channels\"] = data.get(\"channels\", 3)  # get image channels, default to 3\n","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/ultralytics/ultralytics/blob/0449ea011cfd6c9a0d50a0bf1043aca5190cd476/ultralytics/data/utils.py#L504-L540","documentation":"Raised by check_det_dataset when the data YAML declares neither 'names' nor 'nc'. At least one is mandatory: names (list or dict of class names) or nc (integer class count, from which placeholder names class_0..class_{nc-1} are generated). A bare 'names:' that parses to None counts as missing, which is why the check uses `is None` rather than key membership.","triggerScenarios":"train(data='my.yaml') where my.yaml has train:/val: but no names/nc; a YAML with 'names:' written but no classes under it (parses to None); commenting out names while leaving nc out.","commonSituations":"Truncated or template YAMLs; users who assume class names come from the model checkpoint instead of the dataset YAML; indentation bugs that orphan the names entries.","solutions":["Add a names mapping, e.g. 'names:\\n  0: person\\n  1: car'","Or add 'nc: <int>' to get auto-generated placeholder names class_0..class_{nc-1}","If names was already written, verify it is not empty/null in the parsed YAML (print(YAML.load(...)))","Check indentation — entries under names: must be indented one level"],"exampleFix":"# before (my.yaml)\ntrain: images/train\nval: images/val\n\n# after\ntrain: images/train\nval: images/val\nnames:\n  0: cat\n  1: dog","handlingStrategy":"validation","validationCode":"from ultralytics.utils import YAML\n\ndef validate_classes(path: str) -> dict:\n    data = YAML.load(path)\n    if data.get('names') is None and 'nc' not in data:\n        raise ValueError(f\"{path} must define either 'names:' or 'nc:'\")\n    return data","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer explicit 'names:' dicts over bare nc so classes are self-documenting","Never leave 'names:' or 'nc:' empty — delete the line instead","Generate YAMLs from your labels dir with a small script so names are never forgotten"],"tags":["dataset-yaml","names","nc","config","syntaxerror"],"backgroundTag":null,"analyzedSha":"0449ea011cfd6c9a0d50a0bf1043aca5190cd476","analyzedAt":"2026-08-15T02:34:13.413Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}