{"record":{"id":"14612510178e9201","repo":"roboflow/supervision","slug":"invalid-vlm-result-type-type-result-must-be-s","errorCode":null,"errorMessage":"Invalid VLM result type: {type(result)}. Must be str.","messagePattern":"Invalid VLM result type: (.+?)\\. Must be str\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/detection/core.py","lineNumber":2029,"sourceCode":"            >>> detections.xyxy\n            array([[ 580.58057 ,  270.27026 , 1000.      ,  904.9049  ],\n                   [  26.026026,   31.03103 ,  632.6326  ,  998.999   ]],\n                  dtype=float32)\n            >>> detections.class_id\n            array([0, 1])\n            >>> detections.data\n            {'class_name': array(['The giraffe at the back', 'The giraffe at the front'],\n                  dtype='<U24')}\n\n            ```\n\n        \"\"\"  # noqa: E501\n\n        vlm = _validate_vlm_parameters(vlm, result, kwargs)\n\n        if vlm == VLM.PALIGEMMA:\n            if not isinstance(result, str):\n                raise ValueError(\n                    f\"Invalid VLM result type: {type(result)}. Must be str.\"\n                )\n            xyxy, class_id, class_name = from_paligemma(result, **kwargs)\n            data: _DetectionDataType = {\n                CLASS_NAME_DATA_FIELD: class_name,\n            }\n            return cls(xyxy=xyxy, class_id=class_id, data=data)\n\n        if vlm == VLM.QWEN_2_5_VL:\n            if not isinstance(result, str):\n                raise ValueError(\n                    f\"Invalid VLM result type: {type(result)}. Must be str.\"\n                )\n            xyxy, class_id, class_name = from_qwen_2_5_vl(result, **kwargs)\n            data = {CLASS_NAME_DATA_FIELD: class_name}\n            confidence_arr: npt.NDArray[np.floating[Any]] = np.ones(\n                len(xyxy), dtype=float\n            )","sourceCodeStart":2011,"sourceCodeEnd":2047,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/detection/core.py#L2011-L2047","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\noutputs = model.generate(**inputs)\ndetections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=outputs)  # tensor\n\n# after\nimport supervision as sv\ntext = processor.decode(outputs[0], skip_special_tokens=False)\ndetections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=text)","handlingStrategy":"type-guard","validationCode":"text = (\n    result if isinstance(result, str)\n    else processor.decode(result[0], skip_special_tokens=False)\n)\nassert isinstance(text, str)\ndetections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=text)","typeGuard":"def paligemma_result_str(result) -> bool:\n    return isinstance(result, str)","tryCatchPattern":"try:\n    detections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=result)\nexcept ValueError as e:\n    if 'Must be str' in str(e):\n        result = processor.decode(result[0], skip_special_tokens=False)\n        detections = sv.Detections.from_vlm(vlm=sv.VLM.PALIGEMMA, result=result)\n    else:\n        raise","preventionTips":["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"],"tags":["vlm","paligemma","type","from-vlm","decode"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}