HumanSignal/label-studio · error · ValidationError
load_tasks: No data found in DATA or in FILES
Error message
load_tasks: No data found in DATA or in FILES
What it means
async_import dispatches on request content type: file upload (multipart), urlencoded url import, or JSON body with tasks. If none of these branches matched — no FILES, not urlencoded, and body not a JSON list/dict of tasks — it falls into the 'incorrect data source' else branch and raises this ValidationError. It is the 'we received nothing importable' error.
Source
Thrown at label_studio/data_import/api.py:409
if not url:
raise ValidationError('"url" is not found in request data')
if len(url) > 2048:
raise ValidationError('"url" must be 2048 characters or fewer')
project_import.url = url
project_import.save(update_fields=['url'])
# take one task from request DATA
elif 'application/json' in request.content_type and isinstance(request.data, dict):
project_import.tasks = [request.data]
project_import.save(update_fields=['tasks'])
# take many tasks from request DATA
elif 'application/json' in request.content_type and isinstance(request.data, list):
project_import.tasks = request.data
project_import.save(update_fields=['tasks'])
# incorrect data source
else:
raise ValidationError('load_tasks: No data found in DATA or in FILES')
start_job_async_or_sync(
async_import_background,
project_import.id,
request.user.id,
queue_name='high',
on_failure=set_import_background_failure,
project_id=project.id,
organization_id=request.user.active_organization.id,
)
response = {'import': project_import.id}
return Response(response, status=status.HTTP_201_CREATED)
def create(self, request, *args, **kwargs):
commit_to_project = bool_from_request(request.query_params, 'commit_to_project', True)
return_task_ids = bool_from_request(request.query_params, 'return_task_ids', False)
preannotated_from_fields = list_of_strings_from_request(request.query_params, 'preannotated_from_fields', None)View on GitHub (pinned to 0b49e9b539)
Solutions
- Send tasks as a JSON array: requests.post(url, json=[{...task...}]) so Content-Type and body match
- If importing a file, send it as multipart/form-data with the file part (requests files= parameter)
- If importing from a URL, use application/x-www-form-urlencoded with a non-empty 'url' field
- Log/inspect the exact request body and Content-Type actually sent (curl -v) to see which branch failed
- Ensure upstream data generation is not producing an empty payload
Example fix
# before: string body treated as neither list nor dict
requests.post(url, headers={'Content-Type': 'application/json'}, data='{"data": {}}')
# after: proper JSON list of tasks
requests.post(url, json=[{"data": {"text": "hello"}}]) Defensive patterns
Strategy: validation
Validate before calling
assert tasks and isinstance(tasks, list), 'payload must be a non-empty JSON list of tasks' assert all(isinstance(t, dict) and 'data' in t for t in tasks), 'each task must be an object with a data key'
Type guard
def is_valid_import_payload(body) -> bool:
return isinstance(body, list) and len(body) > 0 and all(isinstance(i, dict) for i in body) Try / catch
try:
resp = requests.post(import_url, headers=H, json=tasks)
resp.raise_for_status()
except requests.HTTPError as e:
if 'No data found in DATA or in FILES' in e.response.text:
log.error('Body/Content-Type mismatch: sent %r %r', req_content_type, req_body_preview) Prevention
- Always pair requests json= (or files=) with the matching Content-Type
- Log the final serialized body when debugging import failures
- Fail fast in pipelines when upstream produces zero tasks
- Verify proxies/gateways do not strip request bodies
When it happens
Trigger: POST /api/projects/{id}/import with an empty body; Content-Type application/json but body is an empty string, an empty dict with no recognizable task data handled by earlier branches, or a non-dict/non-list scalar (e.g. plain text body); missing multipart file field with no other data.
Common situations: Client sends JSON with Content-Type: application/json but body serialized as a string of text rather than a JSON array/object; upload script posts a form without the file part; gateway/proxy strips the request body; automation passing an empty list after an upstream job produced no tasks; sending text/csv body with an unsupported content type.
Related errors
- Prediction validation failed ({len(validation_errors)} error
- "url" is not found in request data
- "url" must be 2048 characters or fewer
- preannotated_fields
- Can't deserialize tasks due to {errors}
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/4e4e0f60c3817489.
Report an issue: GitHub.