{"record":{"id":"3b235302555b7974","repo":"HumanSignal/label-studio","slug":"data-is-not-a-list","errorCode":null,"errorMessage":"data is not a list","messagePattern":"data is not a list","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/tasks/validation.py","lineNumber":219,"sourceCode":"        return task\n\n    @staticmethod\n    def format_error(i, detail, item):\n        if len(detail) == 1:\n            code = (str(detail[0].code + ' ')) if detail[0].code != 'invalid' else ''\n            return 'Error {code} at item {i}: {detail} :: {item}'.format(code=code, i=i, detail=detail[0], item=item)\n        else:\n            errors = ', '.join(detail)\n            codes = str([d.code for d in detail])\n            return 'Errors {codes} at item {i}: {errors} :: {item}'.format(codes=codes, i=i, errors=errors, item=item)\n\n    def to_internal_value(self, data):\n        \"\"\"Body of run_validation for all data items\"\"\"\n        if data is None:\n            raise ValidationError('All tasks are empty (None)')\n\n        if not isinstance(data, list):\n            raise ValidationError('data is not a list')\n\n        if len(data) == 0:\n            raise ValidationError('data is empty')\n\n        ret, errors = [], []\n        self.annotation_count, self.prediction_count = 0, 0\n        for i, item in enumerate(data):\n            try:\n                validated = self.validate(item)\n            except ValidationError as exc:\n                error = self.format_error(i, exc.detail, item)\n                errors.append(error)\n                # do not print to user too many errors\n                if len(errors) >= 100:\n                    errors[99] = '...'\n                    break\n            else:\n                ret.append(validated)","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/tasks/validation.py#L201-L237","documentation":"TaskValidator.to_internal_value raises this when the import payload is neither None nor a list — e.g. a dict, string, or number. The import API expects tasks as a JSON array (even for a single task), so any other top-level type is rejected.","triggerScenarios":"POSTing a single task as an object {\"data\": {...}} instead of an array; sending a raw string of task text; sending JSON where the top level is a dict like {\"tasks\": [...]} that wasn't unwrapped.","commonSituations":"Developers assuming the API accepts one task as a bare object; CSV/JSON converters emitting a dict keyed by ID; clients double-serializing so the body becomes a JSON string.","solutions":["Wrap the payload in an array: send [{...}] instead of {...}","If the payload is {\"tasks\": [...]}, extract and send the list value","Parse the body client-side and verify isinstance(payload, list) before POSTing","If sending CSV, use the proper import endpoint/endpoint params so the server converts it to a list"],"exampleFix":"// before\n{\"data\": {\"text\": \"hi\"}}\n// after\n[{\"data\": {\"text\": \"hi\"}}]","handlingStrategy":"type-guard","validationCode":"if not isinstance(tasks, list):\n    tasks = [tasks]  # wrap single task dict into a list","typeGuard":"def is_task_list(tasks):\n    return isinstance(tasks, list) and all(isinstance(t, (dict, object)) for t in tasks)","tryCatchPattern":"try:\n    client.import_tasks(id=project_id, tasks=tasks)\nexcept LabelStudioError as e:\n    if 'data is not a list' in str(e):\n        client.import_tasks(id=project_id, tasks=[tasks] if isinstance(tasks, dict) else list(tasks))\n    else:\n        raise","preventionTips":["Always send a JSON array, even for a single task","Unwrap wrapper objects like {'tasks': [...]} before sending","Avoid double-serialization (passing a JSON string as the body)","Assert isinstance(payload, list) in your import helper"],"tags":["validation","task-import","type-mismatch","rest-api"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}