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 prerequisitesView on GitHub (pinned to 0b49e9b539)
Solutions
- Remove non-.json/.jsonl/.parquet files from the synced location, or move JSON task files into a dedicated prefix/directory
- 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
- Rename/move files that are JSON but have a wrong extension (e.g. .txt) so they end in .json/.jsonl/.parquet
- 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
- Keep JSON task files in a dedicated bucket prefix separate from media assets
- Use the 'Tasks' (blob URL) storage mode when syncing images/audio
- Never rename non-JSON files to .json
- Preview bucket contents before enabling auto-sync
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
- Export storage {self.id}: {failed} annotation(s) failed to e
- Can't import JSON-formatted tasks from {key}. If you're tryi
- Prediction validation failed ({len(validation_errors)} error
- "url" is not found in request data
- "url" must be 2048 characters or fewer
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/ec152fa9af5348f0.
Report an issue: GitHub.