HumanSignal/label-studio · error · ValidationError

Can't parse task data: {extract_message(e)}

Error message

Can't parse task data: {extract_message(e)}

What it means

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.

Source

Thrown at label_studio/tasks/validation.py:148

                class_def = class_def.__name__
            raise ValidationError('Task[{key}] must be {class_def}'.format(key=key, class_def=class_def))

    def validate(self, task):
        """Validate whole task with task['data'] and task['annotations']. task['predictions']"""
        # task is class
        if hasattr(task, 'data'):
            self.check_data_and_root(self.project, task.data)
            return task

        # self.instance is loaded by get_object of view
        if self.instance and hasattr(self.instance, 'data'):
            if isinstance(self.instance.data, dict):
                data = self.instance.data
            elif isinstance(self.instance.data, str):
                try:
                    data = json.loads(self.instance.data)
                except ValueError as e:
                    raise ValidationError("Can't parse task data: " + extract_message(e))
            else:
                raise ValidationError(
                    'Field "data" must be string or dict, but not "' + type(self.instance.data) + '"'
                )
            self.check_data_and_root(self.instance.project, data)
            return task

        # check task is dict
        if not isinstance(task, dict):
            raise ValidationError('Task root must be dict with "data", "meta", "annotations", "predictions" fields')

        # task[data] | task[annotations] | task[predictions] | task[meta]
        if self.check_allowed(task):
            # task[data]
            self.raise_if_wrong_class(task, 'data', (dict, list))
            self.check_data_and_root(self.project, task['data'])

            # task[annotations]: we can't use AnnotationSerializer for validation

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Repair the Task.data row in the DB: load the string with a lenient parser, fix it, and re-save valid JSON
  2. Find offending tasks by attempting json.loads on each Task.data value and log failures
  3. Re-import the affected tasks from the original source with correct JSON
  4. If from Python objects, serialize with json.dumps (not str()) before storing

Example fix

// before
task.data = str({'text': 'hi'})  # "{'text': 'hi'}" stored
// after
task.data = json.dumps({'text': 'hi'})
Defensive patterns

Strategy: validation

Validate before calling

def ensure_json_string(s):
    try:
        return json.loads(s)
    except ValueError as e:
        raise ValueError(f'corrupt Task.data JSON: {e}')
bad = [t.id for t in Task.objects.all() if isinstance(t.data, str) and not valid_json(t.data)]

Type guard

def is_json_string(v):
    if not isinstance(v, str):
        return False
    try:
        json.loads(v); return True
    except ValueError:
        return False

Try / catch

try:
    serializer.is_valid(raise_exception=True)
except ValidationError as e:
    if str(e.detail[0]).startswith("Can't parse task data"):
        repair_task_data(task.id)  # rewrite the row with corrected JSON

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/2c89883c325ab12f. Report an issue: GitHub.