{"record":{"id":"922722c9bcb88038","repo":"roboflow/supervision","slug":"keypoints-class-id-must-be-given-for-nms-to-be-exe","errorCode":null,"errorMessage":"KeyPoints class_id must be given for NMS to be executed. If you intended to perform class agnostic NMS set class_agnostic=True.","messagePattern":"KeyPoints class_id must be given for NMS to be executed\\. If you intended to perform class agnostic NMS set class_agnostic=True\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/key_points/core.py","lineNumber":1355,"sourceCode":"            from rfdetr import RFDETRKeypointPreview\n\n            image = cv2.imread(\"<SOURCE_IMAGE_PATH>\")\n            model = RFDETRKeypointPreview()\n\n            key_points = model.predict(image)\n            key_points = key_points.with_nms(threshold=0.5)\n            ```\n        \"\"\"\n        if len(self) == 0:\n            return self\n\n        if self.detection_confidence is None:\n            raise ValueError(\n                \"KeyPoints detection_confidence must be given for NMS to be executed.\"\n            )\n\n        if not class_agnostic and self.class_id is None:\n            raise ValueError(\n                \"KeyPoints class_id must be given for NMS to be executed. If \"\n                \"you intended to perform class agnostic NMS set \"\n                \"class_agnostic=True.\"\n            )\n\n        xy = self.xy\n        valid = ~np.all(xy == 0, axis=-1)\n        if self.visible is not None:\n            valid = valid & self.visible\n        x_min = np.min(np.where(valid, xy[..., 0], np.inf), axis=1)\n        y_min = np.min(np.where(valid, xy[..., 1], np.inf), axis=1)\n        x_max = np.max(np.where(valid, xy[..., 0], -np.inf), axis=1)\n        y_max = np.max(np.where(valid, xy[..., 1], -np.inf), axis=1)\n        xyxy = np.stack([x_min, y_min, x_max, y_max], axis=1).astype(np.float32)\n\n        if class_agnostic:\n            predictions = np.hstack([xyxy, self.detection_confidence.reshape(-1, 1)])\n        else:","sourceCodeStart":1337,"sourceCodeEnd":1373,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/key_points/core.py#L1337-L1373","documentation":"Raised by KeyPoints.with_nms() when class_id is None and class_agnostic is False. Standard NMS suppresses overlaps only within the same class, which requires class_id; supervision makes this requirement explicit and tells you the escape hatch: set class_agnostic=True to suppress across all classes without class_id.","triggerScenarios":"Calling key_points.with_nms(threshold=0.5) (class_agnostic defaults to False) on KeyPoints that lack class_id — e.g. a single-person pose result or a connector that does not emit class ids.","commonSituations":"Running NMS on pose/keypoint output from a single-class model that never populated class_id; forgetting that with_nms defaults to class-aware NMS unlike the intended use case.","solutions":["If detections are all one class or class boundaries do not matter: key_points.with_nms(threshold=0.5, class_agnostic=True).","Otherwise pass class_id when constructing KeyPoints so class-aware NMS can group by class."],"exampleFix":"// before\nkp = kp.with_nms(threshold=0.5)  # no class_id -> ValueError\n\n// after\nkp = kp.with_nms(threshold=0.5, class_agnostic=True)","handlingStrategy":"validation","validationCode":"if kp.class_id is None:\n    kp = kp.with_nms(threshold=0.5, class_agnostic=True)\nelse:\n    kp = kp.with_nms(threshold=0.5)","typeGuard":"def nms_kwargs(kp: sv.KeyPoints) -> dict:\n    return {\"class_agnostic\": kp.class_id is None}","tryCatchPattern":null,"preventionTips":["Populate class_id on multi-class KeyPoints so class-aware NMS works.","Default to class_agnostic=True when your pipeline is single-class.","Remember with_nms defaults to class-aware NMS, unlike some other libraries."],"tags":["keypoints","nms","class-id","validation"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}