{"record":{"id":"d869a487150b1bc8","repo":"HumanSignal/label-studio","slug":"not-a-list","errorCode":"not_a_list","errorMessage":"not a list","messagePattern":"not a list","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/tasks/serializers.py","lineNumber":528,"sourceCode":"        return self.context.get('project')\n\n    @staticmethod\n    def format_error(i, detail, item):\n        if len(detail) == 1:\n            code = f' {detail[0].code}' if detail[0].code != 'invalid' else ''\n            return f'Error{code} at item {i}: {detail[0]} :: {item}'\n        else:\n            errors = ', '.join(detail)\n            codes = [d.code for d in detail]\n            return f'Errors {codes} at item {i}: {errors} :: {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({api_settings.NON_FIELD_ERRORS_KEY: 'not a list'}, code='not_a_list')\n\n        if not self.allow_empty and len(data) == 0:\n            if self.parent and self.partial:\n                raise SkipField()\n            raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: 'empty'}, code='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.child.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","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/tasks/serializers.py#L510-L546","documentation":"Raised by TaskListSerializer.to_internal_value when the submitted payload is not a JSON list/array. The bulk import API only accepts arrays of task objects; any other JSON type (object, string, number) is rejected with the non-field error 'not a list' (code not_a_list).","triggerScenarios":"POST to the task import endpoints with a body like {\"data\": {...}} (a bare task object instead of a list), a plain string, or a number, so isinstance(data, list) fails.","commonSituations":"Clients posting a single task object instead of wrapping it in an array; sending CSV-as-string content directly as JSON; SDK misuse where the tasks argument is a dict; older integrations written for a different endpoint shape.","solutions":["Wrap the task(s) in a JSON array: send [{\"data\": {...}}] instead of {\"data\": {...}}","If importing a single task, still submit it as a one-element list","Use the Python SDK's create_tasks/import_tasks helpers which accept a list and format correctly","Check that your client isn't sending multipart/form or raw strings where the endpoint expects a JSON array"],"exampleFix":"// before\nawait fetch(`/api/projects/${id}/import`, { method: 'POST', body: JSON.stringify({ data: { text: 'x' } }) });\n// after\nawait fetch(`/api/projects/${id}/import`, { method: 'POST', body: JSON.stringify([{ data: { text: 'x' } }]) });","handlingStrategy":"type-guard","validationCode":"if (!Array.isArray(tasks)) throw new Error('import payload must be a JSON array of task objects');","typeGuard":"function isTaskList(v) {\n  return Array.isArray(v) && v.every(t => typeof t === 'object' && t !== null && 'data' in t);\n}","tryCatchPattern":"try {\n  await importTasks(projectId, payload);\n} catch (e) {\n  if (JSON.stringify(e.response?.data || {}).includes('not a list')) {\n    payload = Array.isArray(payload) ? payload : [payload]; // wrap single object\n    return importTasks(projectId, payload);\n  } throw e;\n}","preventionTips":["Always send an array, even for a single task","Verify Content-Type is application/json and the body parses as an array","Use typed SDK helpers rather than hand-rolled fetch bodies"],"tags":["validation","type-error","bulk-import","tasks","json"],"backgroundTag":"payload-type-mismatch","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}