{"record":{"id":"a4fd66d04d4ee4c6","repo":"roboflow/supervision","slug":"class-id-is-required-for-createml-export-but-the","errorCode":null,"errorMessage":"class_id is required for CreateML export, but the provided Detections has class_id=None.","messagePattern":"class_id is required for CreateML export, but the provided Detections has class_id=None\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/formats/createml.py","lineNumber":264,"sourceCode":"        ```pycon\n        >>> import numpy as np\n        >>> import supervision as sv\n        >>> from supervision.dataset.formats.createml import (\n        ...     detections_to_createml_annotations,\n        ... )\n        >>> detections = sv.Detections(\n        ...     xyxy=np.array([[40, 40, 60, 60]], dtype=np.float32),\n        ...     class_id=np.array([0], dtype=int),\n        ... )\n        >>> detections_to_createml_annotations(detections, classes=[\"dog\"])\n        [{'label': 'dog', 'coordinates':\n          {'x': 50.0, 'y': 50.0, 'width': 20.0, 'height': 20.0}}]\n\n        ```\n    \"\"\"\n    class_ids = detections.class_id\n    if class_ids is None:\n        raise ValueError(\n            \"class_id is required for CreateML export, but the provided \"\n            \"Detections has class_id=None.\"\n        )\n    annotations: list[CreateMLDict] = []\n    for xyxy, class_id in zip(detections.xyxy, class_ids):\n        x_min, y_min, x_max, y_max = (float(value) for value in xyxy)\n        annotations.append(\n            {\n                \"label\": classes[int(class_id)],\n                \"coordinates\": {\n                    \"x\": (x_min + x_max) / 2,\n                    \"y\": (y_min + y_max) / 2,\n                    \"width\": x_max - x_min,\n                    \"height\": y_max - y_min,\n                },\n            }\n        )\n    return annotations","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/formats/createml.py#L246-L282","documentation":"Raised by detections_to_createml_annotations when detections.class_id is None. CreateML annotations label every box via classes[class_id], so a class-less Detections cannot be exported. Unlike the COCO path (per-detection check), this check is on the whole array up front.","triggerScenarios":"Building sv.Detections(xyxy=..., confidence=...) without class_id, then calling detections_to_createml_annotations or save_createml_annotations (DetectionDataset.as_createml).","commonSituations":"Detector outputs that omit class_id (class-agnostic NMS); custom box lists for dataset conversion; slicing/filtering Detections and dropping the class_id field.","solutions":["Attach class_id when constructing Detections: sv.Detections(xyxy=boxes, class_id=np.zeros(len(boxes), dtype=int)).","Re-run inference with a multi-class model that emits class_id.","Guard before export: if detections.class_id is None: raise your own error with context."],"exampleFix":"// before\ndetections = sv.Detections(xyxy=boxes)\ndetections_to_createml_annotations(detections, classes=[\"dog\"])\n\n// after\ndetections = sv.Detections(xyxy=boxes, class_id=np.zeros(len(boxes), dtype=int))\ndetections_to_createml_annotations(detections, classes=[\"dog\"])","handlingStrategy":"type-guard","validationCode":"if detections.class_id is None:\n    detections = sv.Detections(\n        xyxy=detections.xyxy,\n        confidence=detections.confidence,\n        class_id=np.zeros(len(detections), dtype=int),  # single-class default\n    )","typeGuard":"def has_class_id(dets: sv.Detections) -> bool:\n    \"\"\"True when class_id is present and index-aligned with xyxy.\"\"\"\n    return dets.class_id is not None and len(dets.class_id) == len(dets.xyxy)","tryCatchPattern":"try:\n    save_createml_annotations(dataset=ds, annotation_path=p)\nexcept ValueError as exc:\n    if \"class_id\" in str(exc):\n        raise RuntimeError(\"Detections are class-agnostic; assign class ids first\") from exc\n    raise","preventionTips":["Always pair xyxy with class_id when building Detections.","Centralize Detections construction in one factory that enforces class_id presence.","For class-agnostic models, define a single class and emit zeros."],"tags":["createml","detections","class-id","dataset-export"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}