HumanSignal/label-studio · error · ValueError
If you use "annotations" field in the task, you must put "da
Error message
If you use "annotations" field in the task, you must put "data" field in the task too
What it means
add_task also requires that dicts carrying pre-made annotations include the task payload. A non-empty 'annotations' list without a 'data' key gives the annotations nothing to attach to, so a ValueError is raised and the task is not created.
Source
Thrown at label_studio/io_storages/base_models.py:511
link_kwargs = asdict(link_object)
data = link_kwargs.pop('task_data', None)
allow_skip = data.get('allow_skip', True)
# predictions
predictions = data.get('predictions') or []
if predictions:
if 'data' not in data:
raise ValueError(
'If you use "predictions" field in the task, you must put "data" field in the task too'
)
# annotations
annotations = data.get('annotations') or []
cancelled_annotations = 0
if annotations:
if 'data' not in data:
raise ValueError(
'If you use "annotations" field in the task, you must put "data" field in the task too'
)
cancelled_annotations = len([a for a in annotations if a.get('was_cancelled', False)])
storage_task_data_validator = load_func(getattr(settings, 'STORAGE_TASK_DATA_VALIDATOR', None))
if storage_task_data_validator:
storage_task_data_validator(project, data)
if 'data' in data and isinstance(data['data'], dict):
if data['data'] is not None:
data = data['data']
else:
data.pop('data')
with transaction.atomic():
# Create task without skip_fsm (it's not a model field)
task = Task(
data=data,View on GitHub (pinned to 0b49e9b539)
Solutions
- Include the 'data' field with the task payload in every dict that has 'annotations'.
- Remove the 'annotations' field if you intend a plain data import (annotations can be added later via the API).
- Validate the import file structure before calling add_task: data required whenever annotations or predictions exist.
Example fix
// before
task = {'annotations': [{'result': [...], 'was_cancelled': False}]}
storage.add_task(task)
// after
task = {'data': {'image': 's3://bucket/img.jpg'}, 'annotations': [{'result': [...], 'was_cancelled': False}]}
storage.add_task(task) Defensive patterns
Strategy: validation
Validate before calling
def validate_task_payload(task: dict):
if isinstance(task, dict) and task.get('annotations') and 'data' not in task:
raise ValueError('Task payload with annotations must also include "data"') Type guard
def is_valid_task_payload(task: dict) -> bool:
return not (isinstance(task, dict) and task.get('annotations') and 'data' not in task) Try / catch
try:
storage.add_task(task)
except ValueError as e:
if '"data" field in the task' in str(e):
logger.error('Malformed task payload (missing data): %s', task)
else:
raise Prevention
- Include the 'data' key in every imported task dict that carries annotations.
- Check export/import conversion scripts so they never emit annotations without data.
- Add schema validation (e.g. jsonschema) for import files requiring 'data' when 'annotations' is present.
When it happens
Trigger: Calling add_task (or the storage sync / create_tasks paths) with a dict like {'annotations': [...]} that lacks 'data'.
Common situations: Re-importing exported annotations without their data payloads; importing completions from another tool; conversion scripts that copy only the annotations arrays.
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
- If you use "predictions" field in the task, you must put "da
- It's expected to have 'email' field in 'completed_by' data i
- Prediction validation failed ({len(validation_errors)} error
- "url" must be 2048 characters or fewer
- preannotated_fields
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/e18c2ae6c70a2091.
Report an issue: GitHub.