0.30.3
triggerdotdev/trigger.dev0.30.3Sep 14, 2026by Borda
Upgrading?
AI Summary
A bug-fix release addressing pose estimation crashes, VLM parsing errors, and integer overflow in geometry utilities.
Key Highlights
- Fixed crashes on non-finite key points (NaN) in pose estimation pipelines.
- Fixed VLM box corner ordering to prevent false IoU misses.
- Fixed integer overflow in `sv.pad_boxes` and `sv.scale_boxes`.
- Fixed video processing hanging when `max_frames` exceeds video length.
Breaking Changes
- `sv.pad_boxes` now returns `int64` instead of the input dtype for integer inputs.
Full Release Notes
# 0.30.3: Pose, VLM, and video/CSV crash and correctness fixes
supervision 0.30.3 is a bug-fix release closing crash and silent-correctness gaps across pose estimation, VLM parsing, video/CSV output, and geometry utilities. Non-finite key points — how pose estimators report an undetected joint — no longer produce duplicate poses that survive `sv.KeyPoints.with_nms`, or crash the key point annotators outright. `sv.Detections.from_vlm` now orders backwards box corners, closing a bug where such a box scored a false `0.0` IoU and both survived NMS as a duplicate and counted as a total miss in mAP. `sv.TraceAnnotator` and `sv.CSVSink` no longer crash or silently drop columns on the first frame with no detections — a case every non-`ByteTrack` tracker pipeline hits. `sv.process_video` no longer hangs forever when `max_frames` exceeds the video length. Continuing 0.30.2's numeric-correctness theme, `sv.pad_boxes` and `sv.scale_boxes` are fixed against integer overflow. No breaking API changes, no new public API.
## ✨ Spotlights / highlights
### Non-finite key points no longer produce duplicate poses or crash annotators
`sv.KeyPoints.with_nms` tested key point validity with `xy == 0` alone, and `NaN` — how pose estimators report an undetected joint — is not `0`. The stale joint stayed in the NMS box, so a duplicate skeleton scored `False` on every IoU comparison against it and survived suppression. The key point annotators (`sv.VertexAnnotator`, `sv.EdgeAnnotator`, `sv.VertexLabelAnnotator`, the `sv.VertexEllipse*Annotator` family) had the matching crash: a single undetected joint raised `ValueError: cannot convert float NaN to integer` for the whole frame. Both now skip non-finite coordinates, matching `sv.KeyPoints.as_detections`.
```python
keypoints = sv.KeyPoints(xy=xy, confidence=confidence)
keypoints.with_nms(
threshold=0.5
) # duplicate skeletons with a NaN joint are now suppressed
```
### `sv.Detections.from_vlm` no longer scores a false IoU miss on backwards box corners
A VLM that emits a corner pair backwards produced an `xyxy` row with `x_min > x_max`. Nothing downstream caught it: `sv.box_iou_batch` clamps intersection width at zero, so the box scored `0.0` IoU against itself — surviving NMS as a duplicate and counting as a total miss in mAP — while `box_area` still reported a plausible positive value. Every VLM parser now orders each box's corners before returning it.
### `sv.TraceAnnotator` and `sv.CSVSink` no longer crash or silently corrupt output on an empty-detections frame
`sv.TraceAnnotator.annotate` raised `ValueError: The tracker_id field is missing` on the first frame with no detections, for every tracker except `sv.ByteTrack`. Such a frame now draws nothing and still advances the frame counter, so `trace_length` stays a window over elapsed frames rather than only over populated ones. `sv.CSVSink` had a quieter failure: an empty batch fixed the CSV header without the `data`/`custom_data` columns, and every later row was silently truncated to that schema — dropping fields like `class_name` for the whole file. The header is now fixed by the first batch that actually carries detections.
### `sv.process_video` no longer hangs forever when `max_frames` exceeds the video length
The reader thread failed on the out-of-range `end` before enqueuing its sentinel, leaving the main loop blocked on the read queue indefinitely. `max_frames` is now capped at the video length, and any reader-thread error surfaces as `RuntimeError("Reader thread raised: ...")` instead of stalling the call.
### Integer-coordinate overflow fixed in `sv.pad_boxes` and `sv.scale_boxes`
Both computed intermediate values that could overflow or silently wrap for large integer coordinates (e.g. large `int32`/`uint16`/`int64` boxes). Both now use overflow-safe arithmetic.
```python
xyxy = np.array([[10, 20, 30, 40]], dtype=np.int64)
sv.pad_boxes(xyxy=xyxy, px=5, py=10) # int64 output, no wraparound
```
`pad_boxes` changes return dtype for integer input — see the migration guide below.
### `sv.scale_image` and `sv.resize_image(keep_aspect_ratio=True)` no longer crash on an extreme aspect ratio or tiny scale factor
A small enough factor — or an aspect ratio too extreme for the target box — could round an output axis down to `0`, and `cv2.resize` raised an assertion naming nothing the caller passed. Each axis now keeps at least one pixel. Two callers inherit the fix: `sv.letterbox_image` could not fill the resolution it was asked for, and `sv.CropAnnotator` with `scale_factor < 1` aborted the whole frame as soon as one detection box was a few pixels across.
## 🔄 Migration guide
No breaking API changes. One fix changes return dtype for integer input:
- `sv.pad_boxes` — integer `xyxy` now returns `int64` (or `float64` if a padded coordinate exceeds the `int64` range), instead of the input's original integer dtype, which could silently overflow or wrap for small dtypes like `int16`/`uint8`.
If your code assumes `pad_boxes` preserves the input's exact dtype (e.g. reusing the result as an `int16` array), cast explicitly: `sv.pad_boxes(...).astype(np.int16)`.
`sv.scale_boxes` also fixes an integer-overflow bug, but its return dtype was already `float64` for integer input before this release — unaffected.
## 📝 Notable changes
### 🔧 Fixed
- `sv.Detections.from_ultralytics` now assigns the placeholder class ID `0` to every mask in a masks-only result, instead of sequential IDs across masks that belong to the same image. (#2566)
- `sv.pad_boxes` now computes integer-coordinate padding without overflow or unsigned casting errors. (#2565)
- `sv.scale_image` and `sv.resize_image(keep_aspect_ratio=True)` no longer derive a zero-sized target, fixing a crash reached via `sv.letterbox_image` and `sv.CropAnnotator`. (#2564)
- `sv.KeyPoints.with_nms` no longer stops suppressing duplicate skeletons as soon as a key point is non-finite. (#2563)
- `sv.tint_image` no longer tints the caller's own image array in place. (#2562)
- `sv.LineZone` no longer consumes the `triggering_anchors` iterable during validation, so a generator or `map` passed in is no longer exhausted before the first `trigger()` call. (#2561)
- The key point annotators now skip key points whose coordinates are not finite instead of raising `ValueError`. (#2560)
- `sv.PolygonZone` now rejects a polygon with fewer than three vertices instead of building a zone that can never trigger; `sv.Detections.from_vlm` now orders each parsed box's corners. (#2554)
- `sv.ClassificationDataset.as_folder_structure` now rejects images that would overwrite the same class-relative filename before writing any files. (#2551)
- `sv.process_video` no longer hangs forever when `max_frames` is larger than the number of frames in the video. (#2546)
- `sv.filter_polygons_by_area` and `sv.approximate_polygon` now preserve local geometry for large-origin integer and `float64` polygons. (#2542)
- `sv.TraceAnnotator.annotate` no longer raises on an empty-detections frame; `sv.CSVSink` no longer lets an empty batch fix the CSV header. (#2539)
- `sv.scale_boxes` now preserves exact integer intermediates, preventing overflow and scaled-corner rounding errors for large integer-coordinate boxes. (#2541)
- A release's own version-pinned docs no longer show the outdated-version banner on the day it ships, and the docs-publish and canonical-backfill workflows now share one `gh-pages` write lock instead of racing each other. (#2536)
## 🏆 Contributors
- **kevin** (@kevin9327) — fixed `KeyPoints.with_nms`/key point annotators crashing on non-finite key points, `tint_image` image aliasing, `LineZone` generator exhaustion, and the `scale_image`/`resize_image` zero-target crash
- **Durgamani Sasikumar** (@tedo001, [LinkedIn](https://www.linkedin.com/in/durgamani-sasikumar)) — fixed `PolygonZone`/`from_vlm` box-corner ordering and the `TraceAnnotator`/`CSVSink` empty-frame crash
- **S B Pranay** (@pranaysb, [LinkedIn](https://www.linkedin.com/in/pranaysb/)) — fixed integer overflow in `scale_boxes` and dtype loss in `filter_polygons_by_area`/`approximate_polygon`
- **JiantaoPeng** (@PengJianT) — fixed `from_ultralytics` masks-only class ID sizing
- **trueoneplusone** (@trueoneplusone) — fixed integer overflow in `pad_boxes`
- **Andrew Barnes** (@Bortlesboat, [LinkedIn](https://www.linkedin.com/in/andrew-barnes-705a08195/)) — fixed classification export filename collisions
- **Abhijith Neil Abraham** (@abhijithneilabraham, [LinkedIn](https://www.linkedin.com/in/abhijith-neil-abraham-765165141)) — fixed `process_video` hanging when `max_frames` exceeds the video length
- **Jirka Borovec** (@Borda, [LinkedIn](https://linkedin.com/in/jirka-borovec)) — fixed the release-day outdated-docs banner
______________________________________________________________________
**Full changelog**: https://github.com/roboflow/supervision/compare/0.30.2...0.30.3
Related Repositories
openclaw/openclaw★ 392,689
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
nilbuild/developer-roadmap★ 370,064
Interactive roadmaps, guides and other educational content to help developers grow in their careers.
morluto/rea★ 357,450
Reverse engineer anything with agents, from app behavior down to native binaries.
anomalyco/opencode★ 219,652
The open source coding agent.
n8n-io/n8n★ 208,248
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.