HumanSignal/label-studio · warning · ValidationError
{e.detail[0]} [assume: item as is = task root with values]
Error message
{e.detail[0]} [assume: item as is = task root with values] What it means
check_data_and_root wraps check_data: when the inner validation fails and dict_is_root=True, it re-raises the original message plus the hint " [assume: item as is = task root with values] ". This variant fires when the submitted item had NO 'data' field, so Label Studio treated the item itself as the data payload (validate()'s else-branch calls check_data_and_root(project, task, dict_is_root=True)), and that data also failed validation.
Source
Thrown at label_studio/tasks/validation.py:111
)
)
return data
@staticmethod
def check_data_and_root(project, data, dict_is_root=False):
"""Check data consistent and data is dict with task or dict['task'] is task
:param project:
:param data:
:param dict_is_root:
:return:
"""
try:
TaskValidator.check_data(project, data)
except ValidationError as e:
if dict_is_root:
raise ValidationError(e.detail[0] + ' [assume: item as is = task root with values] ')
else:
raise ValidationError(e.detail[0] + ' [assume: item["data"] = task root with values]')
@staticmethod
def check_allowed(task):
# task is required
if 'data' not in task:
return False
# everything is ok
return True
@staticmethod
def raise_if_wrong_class(task, key, class_def):
if key in task and not isinstance(task[key], class_def):
if isinstance(class_def, tuple):
class_def = ' or '.join([c.__name__ for c in class_def])
else:View on GitHub (pinned to 0b49e9b539)
Solutions
- Read the prefix of the message (the e.detail[0] part) to find the real validation failure, then fix that in the item
- Prefer wrapping payloads explicitly: {'data': {...}} so the root-assumption path is never taken
- Ensure the unwrapped item's keys match the config variables and their expected types
- Normalize the whole batch to one shape (all wrapped or all bare data dicts) before import
Example fix
// before
import_tasks([{'text': 123}]) # config <Text value="$text"/> but Text won't accept... wait, 123 is fine; e.g. {'img': {'url': 'x'}}
// after
import_tasks([{'data': {'img': 'x'}}]) # or fix the inner failure indicated before the hint Defensive patterns
Strategy: validation
Validate before calling
def is_wrapped(item):
return isinstance(item, dict) and 'data' in item
bad = [i for i, t in enumerate(items) if not is_wrapped(t)]
if bad:
items = [{'data': t} if isinstance(t, dict) else {'data': {}} for t in items] Type guard
def is_bare_data_dict(item):
return isinstance(item, dict) and 'data' not in item Try / catch
try:
import_tasks(items)
except ValidationError as e:
msg = str(e.detail[0])
if 'item as is = task root' in msg:
items = [{'data': it} for it in items] # switch to explicit wrapping
import_tasks(items) Prevention
- Always use the explicit {'data': ...} wrapper in imports
- Mixing wrapped and bare items in one batch makes root-assumption errors hard to read
- Read the message prefix before the '[assume:' hint — it names the real failure
When it happens
Trigger: Importing an item like {'text': 'hello'} (no 'data' key) where 'text' itself fails check_data (missing required config key, wrong type, etc.); validate() falls to the else-branch and validates the item as data with dict_is_root=True.
Common situations: Bulk imports that submit raw data dicts without wrapping in {'data': ...}; users assuming top-level keys like annotations/predictions can sit beside unwrapped data; mixed batches where some items are wrapped and some are not.
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
- Task is empty (None)
- {e.detail[0]} [assume: item["data"] = task root with values]
- Maximum task number is {settings.TASKS_MAX_NUMBER}, current
- Maximum total size of all files is {settings.TASKS_MAX_FILE_
- {ext} extension is not supported
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/b9b053d10f66884f.
Report an issue: GitHub.