HumanSignal/label-studio · error · UnsupportedFileFormatError

File "{key}" is not a JSON/JSONL/Parquet file. Only .json, .

Error message

File "{key}" is not a JSON/JSONL/Parquet file. Only .json, .jsonl, and .parquet files can be processed.\nIf you're trying to import non-JSON data (images, audio, text, etc.), edit storage settings and enable "Tasks" import method

What it means

UnsupportedFileFormatError is raised by _scan_and_create_links during a storage sync when a found object's extension is not .json/.jsonl/.parquet and the storage is in JSON-import mode (use_blob_urls False, check_file_extension enabled). The JSON storage type can only parse structured data files, so binary/asset files are rejected instead of becoming tasks.

Source

Thrown at label_studio/io_storages/base_models.py:714

            tasks_existed += link_class.objects.filter(key__in=existing_keys, storage=self.id).count()
            self.info_update_progress(last_sync_count=tasks_created, tasks_existed=tasks_existed)

            for key in deduplicated_keys:
                if key in existing_keys:
                    logger.debug(f'{self.__class__.__name__} already has tasks linked to {key=}')
                    continue

                logger.debug(f'{self}: found new key {key}')

                # Check if file should be processed as JSON based on extension
                # Skip non-JSON files if use_blob_urls is False
                if check_file_extension and not self.use_blob_urls:
                    _, ext = os.path.splitext(key.lower())
                    # Only process files with JSON/JSONL/PARQUET extensions
                    json_extensions = {'.json', '.jsonl', '.parquet'}

                    if ext and ext not in json_extensions:
                        raise UnsupportedFileFormatError(
                            f'File "{key}" is not a JSON/JSONL/Parquet file. Only .json, .jsonl, and .parquet files can be processed.\n'
                            f"If you're trying to import non-JSON data (images, audio, text, etc.), "
                            f'edit storage settings and enable "Tasks" import method'
                        )

                try:
                    link_objects = self.get_data(key)
                except (UnicodeDecodeError, json.decoder.JSONDecodeError) as exc:
                    logger.debug(exc, exc_info=True)
                    raise ValueError(
                        f'Error loading JSON from file "{key}".\nIf you\'re trying to import non-JSON data '
                        f'(images, audio, text, etc.), edit storage settings and enable '
                        f'"Tasks" import method'
                    )

                for link_object in link_objects:
                    # TODO: batch this loop body with add_task -> add_tasks in a single bulk write.
                    # See DIA-2062 for prerequisites

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Remove non-.json/.jsonl/.parquet files from the synced location, or move JSON task files into a dedicated prefix/directory
  2. If you want images/audio to become tasks directly, edit the storage settings and switch import method to 'Tasks' (treat as source URLs / use_blob_urls) instead of JSON parsing
  3. Rename/move files that are JSON but have a wrong extension (e.g. .txt) so they end in .json/.jsonl/.parquet
  4. Disable check_file_extension in code if you intentionally want all keys attempted as JSON

Example fix

// before (bucket contains img01.png and tasks.json -> sync raises)
storage.sync()
// after: filter the storage prefix to a JSON-only path
storage.prefix = 'tasks-json/'
storage.save()
storage.sync()
Defensive patterns

Strategy: validation

Validate before calling

import os
ALLOWED = {'.json', '.jsonl', '.parquet'}
def files_are_supported(keys):
    bad = [k for k in keys if os.path.splitext(k.lower())[1] not in ALLOWED]
    return not bad, bad

Type guard

def is_json_like(key):
    import os
    return os.path.splitext(key.lower())[1] in {'.json', '.jsonl', '.parquet'}

Try / catch

from label_studio.io_storages.base_models import UnsupportedFileFormatError
try:
    storage.scan_and_create_links()
except UnsupportedFileFormatError as e:
    logger.error('Non-JSON object in storage: %s', e)
    # move the file or switch storage import method to Tasks

Prevention

When it happens

Trigger: Running scan_and_create_links on a JSON import storage whose bucket/directory contains .jpg/.png/.txt/.csv files; adding data assets to the same path the JSON storage syncs from.

Common situations: Pointing an import storage at a bucket holding both images and annotation JSON; users who intended the 'Treat every bucket object as a source URL' (Tasks/blob-urls) storage mode but left the storage on JSON import; files uploaded without extension (or uppercase fine — lowercased) being skipped.

Related errors


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