roboflow/supervision · error · ValueError

Failed to parse XML root from

Error message

Failed to parse XML root from {annotation_path}

What it means

Raised while loading a Pascal VOC dataset when ElementTree parses the annotation XML file but tree.getroot() returns None. This only happens for a structurally empty or degenerate XML document (e.g. a zero-byte or whitespace-only .xml file), because xml.etree.ElementTree.parse raises ParseError itself for malformed syntax. The file path is included so you can locate the offending annotation.

Solutions

  1. Check the file named in the error message with `cat`/`ls -la` — it is almost certainly empty or whitespace-only.
  2. Delete or regenerate the broken .xml file (re-export from the source dataset or re-download).
  3. Sweep the annotations directory for other empty XML files: find annotations_dir -name '*.xml' -size -1c
  4. If empty XML means 'no objects', decide whether to remove the file (the loader then treats the image as empty via the missing-file branch) or write a valid <annotation></annotation> root.

Example fix

# before: empty file annotations/0001.xml (0 bytes)
# after: minimal valid Pascal VOC file
with open('annotations/0001.xml', 'w') as f:
    f.write('<annotation></annotation>')
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
import xml.etree.ElementTree as ET

def valid_voc_xml(path: str) -> bool:
    """Check that a Pascal VOC annotation file has a parseable root element."""
    p = Path(path)
    if not p.exists() or p.stat().st_size == 0:
        return False
    try:
        return ET.parse(p).getroot() is not None
    except ET.ParseError:
        return False

Try / catch

try:
    dataset = sv.DetectionDataset.from_pascal_voc(images_dir, ann_dir)
except ValueError as e:
    if 'Failed to parse XML root' in str(e):
        bad = str(e).split('from ')[-1].strip()
        Path(bad).unlink(missing_ok=True)  # or quarantine
        dataset = sv.DetectionDataset.from_pascal_voc(images_dir, ann_dir)
    else:
        raise

Prevention

When it happens

Trigger: Calling DetectionDataset.from_pascal_voc(...) (or the internal load loop in pascal_voc.py) where an image stem has a matching .xml file in the annotations directory that is empty, contains only whitespace, or is otherwise a valid-but-rootless document.

Common situations: Interrupted dataset downloads or exports that left 0-byte .xml files; annotation writers that flush an empty file before crashing; placeholder files created by tooling; filesystem corruption after a bad copy.

Understand the failure class

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/d7052e18d61c92e3. Report an issue: GitHub.

Appendix: source

Thrown at src/supervision/dataset/formats/pascal_voc.py:240

    classes: list[str] = []
    annotations = {}

    for image_path in tqdm(
        image_paths,
        total=len(image_paths),
        desc="Loading Pascal VOC annotations",
        disable=not show_progress,
    ):
        image_stem = Path(image_path).stem
        annotation_path = os.path.join(annotations_directory_path, f"{image_stem}.xml")
        if not os.path.exists(annotation_path):
            annotations[image_path] = Detections.empty()
            continue

        tree = parse(annotation_path)
        root = tree.getroot()
        if root is None:
            raise ValueError(f"Failed to parse XML root from {annotation_path}")

        image = cv2.imread(image_path)
        if image is None:
            raise ValueError(f"Could not read image from path: {image_path}")
        resolution_wh = (image.shape[1], image.shape[0])
        annotation, classes = detections_from_xml_obj(
            root, classes, resolution_wh, force_masks
        )
        annotations[image_path] = annotation

    return classes, image_paths, annotations


def detections_from_xml_obj(
    root: Element,
    classes: list[str],
    resolution_wh: tuple[int, int],
    force_masks: bool = False,

View on GitHub (pinned to 7f254d9784)