roboflow/supervision · error · ValueError

Invalid VLM result type: {type(result)}. Must be dict.

Error message

Invalid VLM result type: {type(result)}. Must be dict.

What it means

The FLORENCE_2 branch of Detections.from_vlm expects the Florence-2 post-processed output as a dict — typically {'<TASK>': value} entries produced by the Florence2Processor, e.g. {'<OD>': 'box1...</od>'} or '<OD>' plus '<OD_SEGMENTS>'. The parser from_florence_2 requires a dict; strings raise this ValueError.

Source

Thrown at src/supervision/detection/core.py:2075

            xyxy, class_id, class_name = from_qwen_3_vl(result, **kwargs)
            data = {CLASS_NAME_DATA_FIELD: class_name}
            confidence_arr = np.ones(len(xyxy), dtype=float)
            return cls(
                xyxy=xyxy, class_id=class_id, confidence=confidence_arr, data=data
            )

        if vlm == VLM.DEEPSEEK_VL_2:
            if not isinstance(result, str):
                raise ValueError(
                    f"Invalid VLM result type: {type(result)}. Must be str."
                )
            xyxy, class_id, class_name = from_deepseek_vl_2(result, **kwargs)
            data = {CLASS_NAME_DATA_FIELD: class_name}
            return cls(xyxy=xyxy, class_id=class_id, data=data)

        if vlm == VLM.FLORENCE_2:
            if not isinstance(result, dict):
                raise ValueError(
                    f"Invalid VLM result type: {type(result)}. Must be dict."
                )
            xyxy, labels, mask, xyxyxyxy = from_florence_2(result, **kwargs)
            if len(xyxy) == 0:
                empty = cls.empty()
                empty.data = {CLASS_NAME_DATA_FIELD: np.empty(0, dtype=str)}
                return empty

            data = {}
            if labels is not None:
                data[CLASS_NAME_DATA_FIELD] = labels
            if xyxyxyxy is not None:
                data[ORIENTED_BOX_COORDINATES] = xyxyxyxy

            return cls(xyxy=xyxy, mask=mask, data=data)

        if vlm == VLM.GOOGLE_GEMINI_2_0:
            if not isinstance(result, str):

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Run outputs through Florence2Processor.post_process_generation(generated_ids, task='<OD>', image_size=(h, w)) and pass the resulting dict.
  2. Keep the whole dict — the parser reads the task keys itself; do not pre-extract strings.
  3. For segmentation use task '<OD_SEGMENTS>'/'<REFERRING_EXPRESSION_SEGMENTATION>' so the dict contains segmentation entries.

Example fix

# before
text = processor.decode(generated_ids[0], skip_special_tokens=False)
detections = sv.Detections.from_vlm(vlm=sv.VLM.FLORENCE_2, result=text)  # str -> ValueError

# after
parsed = processor.post_process_generation(
    text, task='<OD>', image_size=(image.height, image.width)
)
detections = sv.Detections.from_vlm(vlm=sv.VLM.FLORENCE_2, result=parsed)
Defensive patterns

Strategy: type-guard

Validate before calling

parsed = (
    result if isinstance(result, dict)
    else processor.post_process_generation(result, task='<OD>', image_size=(h, w))
)
assert isinstance(parsed, dict)
detections = sv.Detections.from_vlm(vlm=sv.VLM.FLORENCE_2, result=parsed)

Type guard

def is_florence2_result_dict(result) -> bool:
    return isinstance(result, dict)

Try / catch

try:
    detections = sv.Detections.from_vlm(vlm=sv.VLM.FLORENCE_2, result=result)
except ValueError as e:
    if 'Must be dict' in str(e):
        parsed = processor.post_process_generation(result, task='<OD>', image_size=(h, w))
        detections = sv.Detections.from_vlm(vlm=sv.VLM.FLORENCE_2, result=parsed)
    else:
        raise

Prevention

When it happens

Trigger: Calling from_vlm(vlm=sv.VLM.FLORENCE_2, result='box_1 ... ...') with a raw string; passing the decoded generation text instead of processor.post_process_generation(...) output; passing a list of task results.

Common situations: Skipping post_process_generation and decoding generate() output manually; extracting one task's string value from the dict and passing that; using a wrapper that flattens dict output to text.

Related errors


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