roboflow/supervision · error · ValueError

Could not put detections into Trace because Detections do no

Error message

Could not put detections into Trace because Detections do not have tracker_id.

What it means

Raised by `Trace.put(detections)` (the history buffer behind `TraceAnnotator`) when the incoming `Detections` lack `tracker_id`. A trace is a per-object trajectory keyed by tracker id, so detections without tracking ids cannot be attributed to any trace.

Source

Thrown at src/supervision/annotators/utils.py:378

class Trace:
    def __init__(
        self,
        max_size: int | None = None,
        start_frame_id: int = 0,
        anchor: Position = Position.CENTER,
    ) -> None:
        self.current_frame_id = start_frame_id
        self.max_size = max_size
        self.anchor = anchor

        self.frame_id: npt.NDArray[np.int_] = np.array([], dtype=int)
        self.xy: npt.NDArray[np.float32] = np.empty((0, 2), dtype=np.float32)
        self.tracker_id: npt.NDArray[np.int_] = np.array([], dtype=int)

    def put(self, detections: Detections) -> None:
        """Append a frame of detections to the trace history."""
        if detections.tracker_id is None:
            raise ValueError(
                "Could not put detections into Trace because "
                "Detections do not have tracker_id."
            )

        frame_id: npt.NDArray[np.int_] = np.full(
            len(detections), self.current_frame_id, dtype=int
        )
        self.frame_id = np.concatenate([self.frame_id, frame_id])
        self.xy = np.concatenate(
            [
                self.xy,
                detections.get_anchors_coordinates(self.anchor),
            ]
        )
        self.tracker_id = np.concatenate([self.tracker_id, detections.tracker_id])

        unique_frame_id = np.unique(self.frame_id)

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Add a tracker step: `detections = sv.ByteTrack().update_with_detections(detections)` before `TraceAnnotator.annotate`.
  2. If you only need per-frame annotation (no trajectory), use `BoxAnnotator`/`LabelAnnotator` instead of `TraceAnnotator`.
  3. When building synthetic test detections, include `tracker_id=np.array([...])`.

Example fix

# before
annotator = sv.TraceAnnotator()
annotator.annotate(frame.copy(), detections)  # raw detections, no tracker_id

# after
tracker = sv.ByteTrack()
detections = tracker.update_with_detections(detections)
annotator.annotate(frame.copy(), detections)
Defensive patterns

Strategy: type-guard

Validate before calling

from supervision.annotators.utils import PENDING_TRACK_ID

if detections.tracker_id is None:
    detections = tracker.update_with_detections(detections)

Type guard

def has_tracker_id(d) -> bool:
    return d.tracker_id is not None and len(d.tracker_id) == len(d)

Prevention

When it happens

Trigger: Calling `trace_annotator.annotate(scene, detections)` or `trace.put(detections)` on raw model detections that never passed through a tracker; calling `ByteTrack().update_with_detections(...)` but discarding its result and annotating the pre-track detections; annotating every Nth frame after a pipeline refactor dropped the tracker step.

Common situations: Running detection-only models (no tracker in the pipeline) then adding TraceAnnotator; testing annotators on synthetic `Detections(...)` fixtures built without `tracker_id`; branching code where the tracker is only invoked when a flag is set but TraceAnnotator always runs.

Related errors


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