{"record":{"id":"bbc4d44649bd344d","repo":"HumanSignal/label-studio","slug":"incorrect-format-type-result-for-prediction-res","errorCode":null,"errorMessage":"Incorrect format {type(result)} for prediction result {result}","messagePattern":"Incorrect format (.+?) for prediction result (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/tasks/models.py","lineNumber":1159,"sourceCode":"                            'value': result,\n                        }\n                    ]\n\n        elif isinstance(result, (str, numbers.Integral)):\n            # If result is of integral type, it could be a representation of data from single-valued control tags (e.g. Choices, Rating, etc.)\n            for tag, tag_info in project.get_parsed_config().items():\n                tag_type = tag_info['type'].lower()\n                if tag_type in SINGLE_VALUED_TAGS and isinstance(result, SINGLE_VALUED_TAGS[tag_type]):\n                    return [\n                        {\n                            'from_name': tag,\n                            'to_name': ','.join(tag_info['to_name']),\n                            'type': tag_type,\n                            'value': {tag_type: [result]},\n                        }\n                    ]\n        else:\n            raise ValidationError(f'Incorrect format {type(result)} for prediction result {result}')\n\n    def update_task(self):\n        update_fields = ['updated_at']\n\n        # updated_by\n        request = get_current_request()\n        if request:\n            self.task.updated_by = request.user\n            update_fields.append('updated_by')\n\n        self.task.save(update_fields=update_fields, skip_fsm=True)\n\n    def save(self, *args, update_fields=None, **kwargs):\n        if self.project_id is None and self.task_id:\n            logger.warning('project_id is not set for prediction, project_id being set in save method')\n            self.project_id = Task.objects.only('project_id').get(pk=self.task_id).project_id\n            if update_fields is not None:\n                update_fields = {'project_id'}.union(update_fields)","sourceCodeStart":1141,"sourceCodeEnd":1177,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/tasks/models.py#L1141-L1177","documentation":"Prediction.prepare_prediction_result() received a result that is neither a list nor a dict nor a supported scalar (str/int/float for single-value tags), so it cannot be interpreted. ValidationError names the offending Python type and raw value. Only those shapes have defined parsing rules; anything else (e.g. None, bool, tuple, nested nonsense) is rejected.","triggerScenarios":"Passing result=None, result=(...), a boolean, or any non-JSON-serializable/unsupported object when creating/updating a Prediction via the model save path, _create_memory_efficient/_create_legacy, or add_predictions; typically from a bug in the caller (model returned None and the code forwarded it).","commonSituations":"ML backend returning null predictions on failure that get stored verbatim; deserialized JSON where the result key is null; tuples from Python code passed straight in; type confusion between predictions and annotations fields.","solutions":["Ensure result is always a list of region dicts, a dict, or a single scalar (string/number) before creating the Prediction","Handle empty/failed model responses explicitly: skip creating the prediction or use a valid empty list []","Log/inspect the raw backend output to find where None or a tuple is produced","Coerce types at the boundary, e.g. result = list(result) if isinstance(result, tuple) else result"],"exampleFix":"// before\npred = model.predict(data)  # may return None\nPrediction.objects.create(task=task, result=pred)\n// after\npred = model.predict(data)\nif not pred:\n    return  # or raise/log upstream\nPrediction.objects.create(task=task, result=pred)","handlingStrategy":"type-guard","validationCode":"def ensure_supported_result_type(result):\n    if result is None or isinstance(result, (bool, tuple, set)):\n        raise ValueError(f\"unsupported prediction result type {type(result).__name__}\")\n    return result","typeGuard":"def has_supported_result_type(result) -> bool:\n    if isinstance(result, (str, int, float)) and not isinstance(result, bool):\n        return True\n    if isinstance(result, list):\n        return all(isinstance(i, dict) for i in result)\n    return isinstance(result, dict)","tryCatchPattern":"from rest_framework.exceptions import ValidationError\ntry:\n    Prediction.objects.create(task=task, result=pred)\nexcept ValidationError:\n    logger.warning(\"dropping malformed prediction (type=%s)\", type(pred).__name__)\n    return None","preventionTips":["Handle model failures explicitly; never forward None/empty backend output into result","Coerce tuples/sets to list before creating predictions","Add an input-contract assertion at the boundary where backend output becomes a Prediction","Distinguish None (no prediction) from [] (empty result) in your pipeline"],"tags":["prediction","validation","type-error","format"],"backgroundTag":"invalid-prediction-result-format","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}