HumanSignal/label-studio · error · ValidationError
All tasks are empty (None)
Error message
All tasks are empty (None)
What it means
Raised by TaskListSerializer.to_internal_value (the bulk task import serializer) when the entire submitted data payload is null. Since there are no tasks to validate at all, the serializer fails fast with 'All tasks are empty (None)' instead of iterating items.
Source
Thrown at label_studio/tasks/serializers.py:525
@property
def project(self):
return self.context.get('project')
@staticmethod
def format_error(i, detail, item):
if len(detail) == 1:
code = f' {detail[0].code}' if detail[0].code != 'invalid' else ''
return f'Error{code} at item {i}: {detail[0]} :: {item}'
else:
errors = ', '.join(detail)
codes = [d.code for d in detail]
return f'Errors {codes} at item {i}: {errors} :: {item}'
def to_internal_value(self, data):
"""Body of run_validation for all data items"""
if data is None:
raise ValidationError('All tasks are empty (None)')
if not isinstance(data, list):
raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: 'not a list'}, code='not_a_list')
if not self.allow_empty and len(data) == 0:
if self.parent and self.partial:
raise SkipField()
raise ValidationError({api_settings.NON_FIELD_ERRORS_KEY: 'empty'}, code='empty')
ret, errors = [], []
self.annotation_count, self.prediction_count = 0, 0
for i, item in enumerate(data):
try:
validated = self.child.validate(item)
except ValidationError as exc:
error = self.format_error(i, exc.detail, item)
errors.append(error)
# do not print to user too many errorsView on GitHub (pinned to 0b49e9b539)
Solutions
- Ensure the request body contains a non-null list of tasks, e.g. [{"data": {...}}, ...]
- Check your client code for undefined variables being JSON.stringify'd as null before sending
- Verify the upload file field name and that the file actually parsed (JSON/CSV) to a list
- If data may legitimately be empty, guard client-side before calling the API
Example fix
// before
await fetch(`/api/projects/${id}/import`, { method: 'POST', body: JSON.stringify({ tasks: tasksOrNull }) });
// after
if (!Array.isArray(tasks)) throw new Error('tasks must be a non-null list');
await fetch(`/api/projects/${id}/import`, { method: 'POST', body: JSON.stringify({ tasks }) }); Defensive patterns
Strategy: type-guard
Validate before calling
function assertTasksList(tasks) {
if (tasks === null || tasks === undefined) throw new Error('tasks payload is null');
if (!Array.isArray(tasks)) throw new Error('tasks must be an array');
if (tasks.length === 0) console.warn('importing zero tasks');
} Type guard
function isNonNullArray(v) {
return Array.isArray(v) && v !== null;
} Try / catch
try {
await importTasks(projectId, tasks);
} catch (e) {
if (e.response?.data?.non_field_errors?.[0] === 'All tasks are empty (None)') {
console.error('Payload was null — check data extraction step');
} else throw e;
} Prevention
- Validate request body before sending (non-null, non-undefined)
- Avoid JSON.stringify(undefined) which produces undefined/null fields
- Check file upload field names match what the server expects
- Log serialized payloads in CI to catch null regressions
When it happens
Trigger: POSTing to /api/projects/<id>/import or /api/tasks/ with a JSON body whose tasks/data key is explicitly null, or a form/file upload that resolves to None (e.g., missing upload file field decoded to null).
Common situations: API clients sending {"tasks": null}; CSV/JSON file upload where the file field name is wrong so the parsed content is None; scripts that serialize an empty/undefined variable to null instead of an array; ETL jobs with upstream data loss.
Related errors
- not_a_list
- empty
- If you use "predictions" field in the task, you must put "da
- If you use "annotations" field in the task, you must put "da
- required
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/24b7f7be1a7dc611.
Report an issue: GitHub.