{"record":{"id":"592fc06c761d5583","repo":"roboflow/supervision","slug":"missing-tag-in-pascal-voc-annotation","errorCode":null,"errorMessage":"Missing '{tag}' in Pascal VOC annotation.","messagePattern":"Missing '(.+?)' in Pascal VOC annotation\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/formats/pascal_voc.py","lineNumber":398,"sourceCode":"    return obj.find(\"polygon\") is not None\n\n\ndef parse_polygon_points(polygon: Element) -> npt.NDArray[np.int_]:\n    coordinates: list[int] = []\n    for coord in polygon.findall(\".//*\"):\n        if coord.text is None:\n            raise ValueError(\"Missing polygon coordinate value in Pascal VOC.\")\n        coordinates.append(int(coord.text))\n    return np.array(\n        [(coordinates[i], coordinates[i + 1]) for i in range(0, len(coordinates), 2)],\n        dtype=int,\n    )\n\n\ndef _get_required_text(element: Element, tag: str) -> str:\n    child = element.find(tag)\n    if child is None or child.text is None:\n        raise ValueError(f\"Missing '{tag}' in Pascal VOC annotation.\")\n    return child.text\n\n\ndef save_pascal_voc_annotations(\n    dataset: \"DetectionDataset\",\n    annotations_directory_path: str,\n    min_image_area_percentage: float = 0.0,\n    max_image_area_percentage: float = 1.0,\n    approximation_percentage: float = 0.75,\n    show_progress: bool = False,\n) -> None:\n    \"\"\"Write Pascal VOC XML annotation files for every image in *dataset*.\n\n    Args:\n        dataset: Dataset whose annotations are saved.\n        annotations_directory_path: Destination directory for ``.xml`` files;\n            created automatically if it does not exist.\n        min_image_area_percentage: Minimum detection area as a fraction of the","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/formats/pascal_voc.py#L380-L416","documentation":"Raised by _get_required_text in the Pascal VOC loader when a required child element (e.g. name within object, or width/height within size) is missing from the XML or has empty text. It is the generic required-field accessor used while parsing VOC XML annotation objects.","triggerScenarios":"Loading a Pascal VOC XML file via load_pascal_voc_annotations / detections_from_xml_obj where an <object> lacks <name>, or <size> lacks <width>/<height>/<depth>, or any other element fetched through _get_required_text has no text content.","commonSituations":"Truncated or hand-edited XML; converters that omit <name> for objects; XML files from non-standard VOC dialects; elements written as <name/> self-closing (text is None).","solutions":["Open the reported XML file and add the missing element with its text value (e.g. <name>dog</name> inside <object>).","If generating VOC XML yourself, use supervision's object_to_pascal_voc / save_pascal_voc_annotations which always emit required fields.","Validate files with a quick lxml/ElementTree pass checking for empty required tags before bulk loading."],"exampleFix":"// before\n<object><bndbox><xmin>1</xmin>...</bndbox></object>\n\n// after\n<object><name>dog</name><bndbox><xmin>1</xmin>...</bndbox></object>","handlingStrategy":"validation","validationCode":"from pathlib import Path\nfrom xml.etree import ElementTree as ET\n\ndef validate_voc_xml(file_path: str) -> list[str]:\n    \"\"\"Return list of missing required elements in a VOC XML file.\"\"\"\n    root = ET.parse(file_path).getroot()\n    problems = []\n    for tag in (\"size/width\", \"size/height\", \"size/depth\"):\n        el = root.find(tag)\n        if el is None or not (el.text or \"\").strip():\n            problems.append(tag)\n    for obj in root.findall(\"object\"):\n        name = obj.find(\"name\")\n        if name is None or not (name.text or \"\").strip():\n            problems.append(f\"object[{obj.findtext('name', default='?')}]/name\")\n    return problems","typeGuard":"def is_complete_voc_object(obj: ET.Element) -> bool:\n    \"\"\"True when an <object> has non-empty name and bndbox coordinates.\"\"\"\n    name = obj.find(\"name\")\n    bnd = obj.find(\"bndbox\")\n    return (\n        name is not None and bool((name.text or \"\").strip())\n        and bnd is not None\n        and all((bnd.findtext(t) or \"\").strip() for t in (\"xmin\", \"ymin\", \"xmax\", \"ymax\"))\n    )","tryCatchPattern":"try:\n    sv.DetectionDataset.from_pascal_voc(images_directory_path=d, annotations_directory_path=a)\nexcept ValueError as exc:\n    if \"Missing\" in str(exc) and \"Pascal VOC\" in str(exc):\n        problems = validate_voc_xml(str(exc_file))  # identify and repair the file\n        raise ValueError(f\"Incomplete VOC XML: {problems}\") from exc\n    raise","preventionTips":["Generate VOC XML with supervision's object_to_pascal_voc rather than by hand.","Require <name> text on every <object> in your converter output.","Spot-check third-party VOC sets with an ElementTree scan before bulk loading."],"tags":["pascal-voc","xml","dataset-load","schema"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}