HumanSignal/label-studio · error · ValidationError

"url" must be 2048 characters or fewer

Error message

"url" must be 2048 characters or fewer

What it means

In the same urlencoded branch of async_import, after confirming 'url' is present, Label Studio enforces a maximum URL length of 2048 characters and raises this ValidationError for longer URLs. The limit guards against oversized request lines and downstream storage/column constraints.

Source

Thrown at label_studio/data_import/api.py:394

            preannotated_from_fields=preannotated_from_fields,
            commit_to_project=commit_to_project,
            return_task_ids=return_task_ids,
        )

        if len(request.FILES) > 0:
            logger.debug(f'Import from files: {request.FILES}')
            file_upload_ids, could_be_tasks_list = create_file_uploads(request.user, project, request.FILES)
            project_import.file_upload_ids = file_upload_ids
            project_import.could_be_tasks_list = could_be_tasks_list
            project_import.save(update_fields=['file_upload_ids', 'could_be_tasks_list'])
        elif 'application/x-www-form-urlencoded' in request.content_type:
            logger.debug(f'Import from url: {request.data.get("url")}')
            # empty url
            url = request.data.get('url')
            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,

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Shorten the URL: host the file and share a stable short path instead of embedding data in query params
  2. For presigned URLs, reduce signed headers/params or regenerate with fewer options
  3. Download the file and import it as a file upload (multipart) or via application/json tasks instead
  4. Serve the file behind a short alias/redirect on your own domain

Example fix

// before: one giant URL with embedded payload
url=https://example.com/import?data=%5B%7B%22text%22%3A%22...3000+chars...%22%7D%5D
// after: upload tasks directly as JSON
requests.post(f'{LS_URL}/api/projects/1/import', headers=HEADERS, json=[{"text": "..."}])
Defensive patterns

Strategy: validation

Validate before calling

if len(url) > 2048:
    raise ValueError(f'url is {len(url)} chars; import a local copy of the file instead')

Type guard

def is_importable_url(url) -> bool:
    return isinstance(url, str) and url.startswith(('http://', 'https://')) and len(url) <= 2048

Try / catch

try:
    resp = requests.post(import_url, headers=H, data={'url': url})
    resp.raise_for_status()
except requests.HTTPError as e:
    if '2048' in e.response.text:
        fallback_to_file_upload(url)

Prevention

When it happens

Trigger: POST /api/projects/{id}/import with application/x-www-form-urlencoded and a 'url' value longer than 2048 characters — typically a URL embedding a very long query string or a giant data: / presigned URL with many parameters.

Common situations: Cloud storage presigned URLs (S3/GCS/Azure SAS) that include long signatures and expiry params; URLs that encode the whole JSON payload as a query parameter; generated signed URLs from CDNs with many options.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/bf5b67587e3aa721. Report an issue: GitHub.