roboflow/supervision · error · ValueError
Invalid VLM result type: {type(result)}. Must be str.
Error message
Invalid VLM result type: {type(result)}. Must be str. What it means
Inside Detections.from_vlm, the PaliGemma branch parses raw model output text (the <det> token sequence in the PaliGemma prompt format). The parser from_paligemma only accepts str, so any other result type (dict, list, bytes, parsed JSON) raises this ValueError before parsing.
Source
Thrown at src/supervision/detection/core.py:2029
>>> detections.xyxy
array([[ 580.58057 , 270.27026 , 1000. , 904.9049 ],
[ 26.026026, 31.03103 , 632.6326 , 998.999 ]],
dtype=float32)
>>> detections.class_id
array([0, 1])
>>> detections.data
{'class_name': array(['The giraffe at the back', 'The giraffe at the front'],
dtype='<U24')}
```
""" # noqa: E501
vlm = _validate_vlm_parameters(vlm, result, kwargs)
if vlm == VLM.PALIGEMMA:
if not isinstance(result, str):
raise ValueError(
f"Invalid VLM result type: {type(result)}. Must be str."
)
xyxy, class_id, class_name = from_paligemma(result, **kwargs)
data: _DetectionDataType = {
CLASS_NAME_DATA_FIELD: class_name,
}
return cls(xyxy=xyxy, class_id=class_id, data=data)
if vlm == VLM.QWEN_2_5_VL:
if not isinstance(result, str):
raise ValueError(
f"Invalid VLM result type: {type(result)}. Must be str."
)
xyxy, class_id, class_name = from_qwen_2_5_vl(result, **kwargs)
data = {CLASS_NAME_DATA_FIELD: class_name}
confidence_arr: npt.NDArray[np.floating[Any]] = np.ones(
len(xyxy), dtype=float
)View on GitHub (pinned to 7f254d9784)
Solutions
- Decode the model output to its raw string with special tokens intact: processor.decode(outputs[0], skip_special_tokens=False) — PaliGemma detection tokens (<det>...) must not be stripped.
- If the result came from an API wrapper, extract the text field before passing.
- Keep skip_special_tokens=False; PaliGemma box tokens are special tokens and are required by the parser.
Example fix
# before outputs = model.generate(**inputs) detections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=outputs) # tensor # after import supervision as sv text = processor.decode(outputs[0], skip_special_tokens=False) detections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=text)
Defensive patterns
Strategy: type-guard
Validate before calling
text = (
result if isinstance(result, str)
else processor.decode(result[0], skip_special_tokens=False)
)
assert isinstance(text, str)
detections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=text) Type guard
def paligemma_result_str(result) -> bool:
return isinstance(result, str) Try / catch
try:
detections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=result)
except ValueError as e:
if 'Must be str' in str(e):
result = processor.decode(result[0], skip_special_tokens=False)
detections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=result)
else:
raise Prevention
- Always decode with skip_special_tokens=False for PaliGemma
- Write one adapter per backend that returns the exact expected type
- Unit-test adapters: assert isinstance before from_vlm
When it happens
Trigger: Calling from_vlm(vlm=sv.VLM.PALIGEMMA, result=...) (or from_lmm with lmm='paligemma') where result is a dict, list of tokens, or an object with a .text attribute instead of the decoded string.
Common situations: Passing the transformers generate() tensor output instead of processor.decode(..., skip_special_tokens=False) text; passing a Roboflow/Hosted API response object or dict; pre-parsing the output with json.loads.
Related errors
- Invalid VLM result type: {type(result)}. Must be dict.
- Invalid type for 'lmm': {type(lmm)}. Must be LMM or str.
- Unsupported VLM value: {vlm}.
- Value must be a np.ndarray or a list
- SAM segmentations must all be dense arrays or COCO RLE dicti
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/14612510178e9201.
Report an issue: GitHub.