roboflow/supervision · error · ValueError
F1Score metric requires `class_id` and `confidence` on predi
Error message
F1Score metric requires `class_id` and `confidence` on predictions.
What it means
Raised by F1Score.update() when an image contains only predictions and no targets (e.g. a background image with false positives), but the predictions lack class_id or confidence. The metric needs class_id to bucket false positives per class and confidence to rank predictions across thresholds. Without these fields, per-class F1 statistics cannot be accumulated.
Source
Thrown at src/supervision/metrics/f1_score.py:186
prediction_size_mask = np.ones(len(predictions), dtype=bool)
target_size_mask = np.ones(len(targets), dtype=bool)
if size_category != ObjectSizeCategory.ANY:
if len(predictions) > 0:
prediction_size_mask = (
get_detection_size_category(predictions, self._metric_target)
== size_category.value
)
if len(targets) > 0:
target_size_mask = (
get_detection_size_category(targets, self._metric_target)
== size_category.value
)
if len(targets) == 0 and len(predictions) > 0:
# Only predictions are present (e.g. a background image); every
# prediction is a false positive.
if predictions.class_id is None or predictions.confidence is None:
raise ValueError(
"F1Score metric requires `class_id` and `confidence` "
"on predictions."
)
prediction_class_ids = np.asarray(predictions.class_id, dtype=np.int32)[
prediction_size_mask
]
prediction_confidence = np.asarray(
predictions.confidence, dtype=np.float32
)[prediction_size_mask]
if len(prediction_class_ids) == 0:
continue
stats.append(
(
np.zeros(
(len(prediction_class_ids), iou_thresholds.size),
dtype=np.bool_,
),
np.zeros(View on GitHub (pinned to 7f254d9784)
Solutions
- Attach class_id and confidence to the predictions Detections: Detections(xyxy=..., class_id=np.array([0]), confidence=np.array([0.9]))
- If your model connector drops these fields, keep them: most from_* connectors populate both automatically
- Skip images with no targets before calling update() if you do not want background images scored
Example fix
# before
preds = sv.Detections(xyxy=boxes) # no class_id / confidence
f1.update(targets=sv.Detections.empty(), predictions=preds)
# after
preds = sv.Detections(
xyxy=boxes,
class_id=np.zeros(len(boxes), dtype=np.int32),
confidence=scores,
)
f1.update(targets=sv.Detections.empty(), predictions=preds) Defensive patterns
Strategy: validation
Validate before calling
def has_f1_fields(preds: sv.Detections) -> bool:
return preds.class_id is not None and preds.confidence is not None
if not has_f1_fields(predictions):
raise ValueError('predictions need class_id and confidence before F1') Type guard
def is_f1_ready(dets: sv.Detections) -> bool:
"""True when class_id and confidence are populated."""
return dets.class_id is not None and dets.confidence is not None Try / catch
try:
f1.update(targets=targets, predictions=predictions)
except ValueError as e:
if 'class_id and confidence' in str(e):
predictions.class_id = predictions.class_id or np.zeros(len(predictions), dtype=np.int32)
else:
raise Prevention
- Always construct predictions via model connectors (from_ultralytics etc.) which fill class_id and confidence
- Write a small assert helper before evaluation loops: assert preds.class_id is not None and preds.confidence is not None
When it happens
Trigger: Calling F1Score().update(targets=empty_detections, predictions=Detections(xyxy=..., class_id=None)) or predictions without a confidence array, on an image where len(targets)==0 and len(predictions)>0.
Common situations: Hand-built Detections objects (e.g. from a custom model connector) that omit confidence; predictions crafted from trackers that drop confidence; test fixtures with empty target sets but populated predictions.
Related errors
- F1Score metric requires `class_id` on both predictions and t
- F1Score metric requires `confidence` on predictions.
- 2D boolean mask row count {mask.shape[0]} does not match obj
- 2D boolean mask column count {mask.shape[1]} does not match
- Cannot filter keypoints with a 2D boolean mask where rows ha
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/0a13574a2a1b9011.
Report an issue: GitHub.