HumanSignal/label-studio · error · ValidationError
"result" field in annotation must be list
Error message
"result" field in annotation must be list
What it means
TaskValidator.validate raises this when an annotation dict has a 'result' key but its value is not a list. The import format requires 'result' to be an array of labeling result objects; any other JSON type (string, dict, null, number) fails this check.
Source
Thrown at label_studio/tasks/validation.py:180
# 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
# because it's much different with validation we need here
self.raise_if_wrong_class(task, 'annotations', list)
for annotation in task.get('annotations', []):
if not isinstance(annotation, dict):
logger.warning('Annotation must be dict, but "%s" found', str(type(annotation)))
continue
ok = 'result' in annotation
if not ok:
raise ValidationError('Annotation must have "result" fields')
# check result is list
if not isinstance(annotation.get('result', []), list):
raise ValidationError('"result" field in annotation must be list')
# task[predictions]
self.raise_if_wrong_class(task, 'predictions', list)
for prediction in task.get('predictions', []):
if not isinstance(prediction, dict):
logger.warning('Prediction must be dict, but "%s" found', str(type(prediction)))
continue
ok = 'result' in prediction
if not ok:
raise ValidationError('Prediction must have "result" fields')
# task[meta]
self.raise_if_wrong_class(task, 'meta', (dict, list))
# task is data as is, validate task as data and move it to task['data']
else:
self.check_data_and_root(self.project, task, dict_is_root=True)View on GitHub (pinned to 0b49e9b539)
Solutions
- Wrap the result value in a list: 'result': [result_obj]
- If result is a dict of multiple results, convert to a list of individual result objects
- Check the incoming JSON for result: null and replace with an empty list or drop the annotation
- Pre-validate with isinstance(a['result'], list) before POSTing
Example fix
// before
{"annotations": [{"result": {"type": "labels", "value": {"labels": ["A"]}}}]}
// after
{"annotations": [{"result": [{"type": "labels", "value": {"labels": ["A"]}}]}]} Defensive patterns
Strategy: type-guard
Validate before calling
for task in tasks:
for a in task.get('annotations', []):
if isinstance(a, dict) and 'result' in a and not isinstance(a['result'], list):
a['result'] = [a['result']] if a['result'] is not None else [] Type guard
def is_annotation(a):
return isinstance(a, dict) and isinstance(a.get('result'), list) Try / catch
try:
client.import_tasks(id=project_id, tasks=tasks)
except LabelStudioError as e:
if 'result" field in annotation must be list' in str(e):
for t in tasks:
for a in t.get('annotations', []):
if 'result' in a and not isinstance(a['result'], list):
a['result'] = [a['result']]
client.import_tasks(id=project_id, tasks=tasks)
else:
raise Prevention
- Wrap single result objects in a list before import
- Convert result maps/dicts into arrays of result objects
- Never emit result: null — use [] or omit the annotation
- Unit-test your export converter output against the Label Studio task schema
When it happens
Trigger: POSTing tasks with {'annotations': [{'result': {'id': 1, ...}}]} (object instead of array) or {'result': 'some string'}; also {'result': null} since isinstance(None, list) is False.
Common situations: Export converters that serialize a single result object instead of wrapping it in an array; JSON template mistakes where 'result' was set to a dict of results keyed by field; clients porting from other labeling formats where results are maps.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Annotation must have "result" fields
- data is not a list
- If you use "annotations" field in the task, you must put "da
- Created annotations are incompatible with provided labeling
- There are {count} annotation(s) created with tag "{control_t
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/5b376954e4d06d09.
Report an issue: GitHub.