Skip to content

fix: return empty int ndarray instead of None for class_id on empty VLM parse#2239

Merged
Borda merged 3 commits into
roboflow:developfrom
YousefZahran1:youssef/fix-vlm-parser-class-id-consistency
May 19, 2026
Merged

fix: return empty int ndarray instead of None for class_id on empty VLM parse#2239
Borda merged 3 commits into
roboflow:developfrom
YousefZahran1:youssef/fix-vlm-parser-class-id-consistency

Conversation

@YousefZahran1

Copy link
Copy Markdown
Contributor

What

On empty-parse paths in two VLM parsers, class_id was returned as None instead of a zero-length ndarray of dtype int, inconsistent with every other exit point in these functions and with the convention established by from_google_gemini_2_5, from_qwen_2_5_vl, and from_qwen_3_vl.

Affected code paths

Function Condition Before After
from_paligemma regex finds no matches None np.empty((0,), dtype=int)
from_google_gemini_2_0 JSONDecodeError None np.empty((0,), dtype=int)
from_google_gemini_2_0 empty bounding-box list None np.empty((0,), dtype=int)

Why it matters

Callers that do class_id.shape, len(class_id), or class_id[mask] immediately after parsing will get an AttributeError / TypeError whenever zero detections are returned — a very common path in production (frame with nothing to detect). Downstream Detections.from_vlm(...) pipelines hit this at runtime while unit tests may pass because they check happy paths.

Changes

  • src/supervision/detection/vlm.py — 3 one-line fixes (no logic change)
  • tests/detection/test_vlm.py — updated 10 test expectations to match the new contract

All 88 tests in tests/detection/test_vlm.py pass.

Fixes #2219

… parse

When from_paligemma or from_google_gemini_2_0 find no detections (no regex
matches, JSON decode error, or empty bounding-box list), they previously
returned None for class_id. All other early-exit and filter paths already
return a zero-length ndarray of dtype int. This inconsistency causes
downstream AttributeError when callers unconditionally call .shape or
iterate over the result.

Affected paths:
- from_paligemma: matches.shape[0] == 0 branch
- from_google_gemini_2_0: JSONDecodeError branch and len(xyxy) == 0 branch

Closes roboflow#2219
@YousefZahran1 YousefZahran1 requested a review from SkalskiP as a code owner April 30, 2026 20:47
@CLAassistant

CLAassistant commented Apr 30, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@Borda

Borda commented Apr 30, 2026

Copy link
Copy Markdown
Member

Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.

@YousefZahran1 could you pls sign ^^ 🦝

@Borda Borda marked this pull request as draft April 30, 2026 21:54
@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78%. Comparing base (f4b0767) to head (8bb5f1d).

Additional details and impacted files
@@           Coverage Diff           @@
##           develop   #2239   +/-   ##
=======================================
  Coverage       78%     78%           
=======================================
  Files           66      66           
  Lines         8374    8374           
=======================================
  Hits          6501    6501           
  Misses        1873    1873           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@YousefZahran1

Copy link
Copy Markdown
Contributor Author

"CLA signed! Ready for review when you have a moment.

@YousefZahran1 YousefZahran1 marked this pull request as ready for review April 30, 2026 22:52
@Borda Borda requested a review from Copilot May 19, 2026 12:23
Comment thread src/supervision/detection/vlm.py Outdated
Co-authored-by: Jirka Borovec <6035284+Borda@users.noreply.github.com>
@Borda Borda added the enhancement New feature or request label May 19, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR standardizes the “empty parse” return contract for VLM parsers so class_id is always a zero-length np.ndarray of dtype=int (instead of None) when no detections are produced, aligning PaliGemma and Gemini 2.0 behavior with other parsers and preventing downstream AttributeError/TypeError on common empty-detection paths (see #2219).

Changes:

  • Update from_paligemma(...) to return np.empty((0,), dtype=int) for class_id when regex matching yields zero detections.
  • Update from_google_gemini_2_0(...) to return np.empty((0,), dtype=int) for class_id on JSON decode failure and when no boxes are parsed.
  • Adjust unit test expectations for those empty-result scenarios.

Quality assessment (n/5):

  • Code quality: 4/5
  • Testing: 4/5
  • Docs: 4/5

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/supervision/detection/vlm.py Align empty-result class_id to an empty int ndarray for PaliGemma and Gemini 2.0 error/empty paths.
tests/detection/test_vlm.py Update expected tuples for empty-result cases to match the new class_id contract.
Comments suppressed due to low confidence (1)

src/supervision/detection/vlm.py:630

  • In the classes is not None branch, class_id = np.array([...]) does not specify dtype=int, so if the class filter removes all detections it returns an empty float array. This undermines the new behavior of returning an empty int ndarray on other empty-result paths; consider forcing dtype=int for consistent downstream handling.
    try:
        data = json.loads(result)
    except json.JSONDecodeError:
        return np.empty((0, 4)), np.empty((0,), dtype=int), np.empty((0,), dtype=str)

Comment thread src/supervision/detection/vlm.py
@Borda Borda merged commit 01ec36b into roboflow:develop May 19, 2026
26 checks passed
@Borda Borda mentioned this pull request Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Design]: Pick one convention for class_id on the error path of VLM parsers

4 participants