HumanSignal/label-studio · error · ValueError

Error loading JSON from file "{key}".\nIf you're trying to i

Error message

Error loading JSON from file "{key}".\nIf you're trying to import non-JSON data (images, audio, text, etc.), edit storage settings and enable "Tasks" import method

What it means

Raised by _scan_and_create_links when self.get_data(key) fails to decode/parse the object as JSON — either a UnicodeDecodeError (not UTF-8 text) or json.JSONDecodeError. The generic ValueError wraps the key so the sync job surfaces which file was unreadable.

Source

Thrown at label_studio/io_storages/base_models.py:724

                # 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
                    try:
                        task = self.add_task(
                            self.project,
                            maximum_annotations,
                            max_inner_id,
                            self,
                            link_object,
                            link_class=link_class,
                        )
                        max_inner_id += 1

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Open the offending key locally and validate it: python -m json.tool file.json — fix the malformed JSON or re-export it
  2. Re-encode the file as UTF-8 without BOM (iconv -f UTF-16 -t UTF-8)
  3. If the file is genuinely not JSON, remove it or change storage import method to 'Tasks' (blob URLs)
  4. If JSONL, confirm each line is valid JSON (some readers expect a whole-file array or per-line objects)

Example fix

# before
iconv -f UTF-8 -t UTF-16 tasks.json > tasks.json  # sync fails
# after
iconv -f UTF-16 -t UTF-8 tasks.json > tasks_utf8.json && python -m json.tool tasks_utf8.json > /dev/null
Defensive patterns

Strategy: validation

Validate before calling

import json
def keys_parse_as_json(get_data, keys):
    bad = []
    for k in keys:
        try:
            data = get_data(k)
            json.loads(data if isinstance(data, str) else data.decode('utf-8'))
        except Exception:
            bad.append(k)
    return not bad, bad

Type guard

def is_utf8_json_bytes(b):
    if not isinstance(b, (bytes, bytearray)):
        return False
    try:
        json.loads(b.decode('utf-8'))
        return True
    except (UnicodeDecodeError, json.JSONDecodeError):
        return False

Try / catch

try:
    storage.scan_and_create_links()
except ValueError as e:
    logger.error('Unparseable storage object: %s', e)
    # repair/re-encode the named file before resyncing

Prevention

When it happens

Trigger: A file with a .json/.jsonl/.parquet extension whose body is invalid JSON (truncated upload, HTML error page saved as .json), or a UTF-16/latin-1 encoded JSON file, synced via scan_and_create_links.

Common situations: Browser-exported JSON saved with a BOM or in UTF-16; partially uploaded/corrupted files; placeholder binary files renamed to .json; a .parquet file being read through a JSON path in older versions.

Related errors


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