{"record":{"id":"2c89883c325ab12f","repo":"HumanSignal/label-studio","slug":"can-t-parse-task-data-extract-message-e","errorCode":null,"errorMessage":"Can't parse task data: {extract_message(e)}","messagePattern":"Can't parse task data: (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/tasks/validation.py","lineNumber":148,"sourceCode":"                class_def = class_def.__name__\n            raise ValidationError('Task[{key}] must be {class_def}'.format(key=key, class_def=class_def))\n\n    def validate(self, task):\n        \"\"\"Validate whole task with task['data'] and task['annotations']. task['predictions']\"\"\"\n        # task is class\n        if hasattr(task, 'data'):\n            self.check_data_and_root(self.project, task.data)\n            return task\n\n        # self.instance is loaded by get_object of view\n        if self.instance and hasattr(self.instance, 'data'):\n            if isinstance(self.instance.data, dict):\n                data = self.instance.data\n            elif isinstance(self.instance.data, str):\n                try:\n                    data = json.loads(self.instance.data)\n                except ValueError as e:\n                    raise ValidationError(\"Can't parse task data: \" + extract_message(e))\n            else:\n                raise ValidationError(\n                    'Field \"data\" must be string or dict, but not \"' + type(self.instance.data) + '\"'\n                )\n            self.check_data_and_root(self.instance.project, data)\n            return task\n\n        # check task is dict\n        if not isinstance(task, dict):\n            raise ValidationError('Task root must be dict with \"data\", \"meta\", \"annotations\", \"predictions\" fields')\n\n        # task[data] | task[annotations] | task[predictions] | task[meta]\n        if self.check_allowed(task):\n            # task[data]\n            self.raise_if_wrong_class(task, 'data', (dict, list))\n            self.check_data_and_root(self.project, task['data'])\n\n            # task[annotations]: we can't use AnnotationSerializer for validation","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/tasks/validation.py#L130-L166","documentation":"In validate(), when validating an existing Task model instance (self.instance with .data), a string-typed instance.data is parsed with ujson.loads; a ValueError (malformed JSON) is re-raised as 'Can't parse task data: <message>'. This catches corrupted or non-JSON strings stored in the Task.data column. Called from to_internal_value when a task is re-validated/updated.","triggerScenarios":"Task.data in the database contains invalid JSON (e.g. NaN, single quotes, truncated write, Python-repr rather than JSON) and the task is re-validated via TaskSerializer/to_internal_value, e.g. on task update or project re-validation.","commonSituations":"Legacy rows written by non-JSON serializers; manual DB edits; data inserted with Python repr (single-quoted) strings; ujson stricter parsing rejecting values standard json might tolerate (or vice versa).","solutions":["Repair the Task.data row in the DB: load the string with a lenient parser, fix it, and re-save valid JSON","Find offending tasks by attempting json.loads on each Task.data value and log failures","Re-import the affected tasks from the original source with correct JSON","If from Python objects, serialize with json.dumps (not str()) before storing"],"exampleFix":"// before\ntask.data = str({'text': 'hi'})  # \"{'text': 'hi'}\" stored\n// after\ntask.data = json.dumps({'text': 'hi'})","handlingStrategy":"validation","validationCode":"def ensure_json_string(s):\n    try:\n        return json.loads(s)\n    except ValueError as e:\n        raise ValueError(f'corrupt Task.data JSON: {e}')\nbad = [t.id for t in Task.objects.all() if isinstance(t.data, str) and not valid_json(t.data)]","typeGuard":"def is_json_string(v):\n    if not isinstance(v, str):\n        return False\n    try:\n        json.loads(v); return True\n    except ValueError:\n        return False","tryCatchPattern":"try:\n    serializer.is_valid(raise_exception=True)\nexcept ValidationError as e:\n    if str(e.detail[0]).startswith(\"Can't parse task data\"):\n        repair_task_data(task.id)  # rewrite the row with corrected JSON","preventionTips":["Only store task.data via json.dumps / the ORM JSONField, never str()","Audit DB rows for unparseable JSON after manual edits or migrations","Note ujson is stricter than stdlib json for some inputs — validate with the same parser"],"tags":["json-parse","database","corrupted-data"],"backgroundTag":"json-parse-error","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}