HumanSignal/label-studio · error · ValidationError

Failed to parse JSON file

Error message

Failed to parse JSON file {self.file_name}: {extract_message(exc)}

What it means

read_tasks_list_from_json_streaming wraps any exception raised while parsing/iterating the JSON file into a single ValidationError that includes the file name and the underlying message via extract_message(exc). It is a catch-all transformer, so the root cause (JSONDecodeError, the 'Unsupported or invalid JSON structure' error, encoding errors, etc.) appears in the message text.

Solutions

  1. Read the wrapped inner message after 'Failed to parse JSON file ...:' and fix the underlying JSON syntax issue
  2. Run the file through a JSON linter / python -m json.tool to locate the syntax error
  3. Re-save the file as UTF-8 and as valid JSON (no trailing commas, comments, or envelope objects)

Example fix

// before: file contains BOM/UTF-16 or trailing comma
{"a": 1,}
// after: valid UTF-8 JSON
{"a": 1}
Defensive patterns

Strategy: try-catch

Validate before calling

import json
raw = open('tasks.json', 'rb').read()
text = raw.decode('utf8')  # raises on wrong encoding
json.loads(text)           # raises with position on bad syntax

Try / catch

try:
    for batch in fu.read_tasks_streaming():
        yield batch
except ValidationError as e:
    # e contains 'Failed to parse JSON file <name>: <inner cause>'
    raise ValueError(f"Fix JSON before import: {e}") from e

Prevention

When it happens

Trigger: Any exception inside the streaming read: invalid JSON syntax (json.loads failure), unsupported top-level structure, decode errors on non-UTF8 bytes, or I/O errors reading the file during read_tasks_streaming.

Common situations: Truncated or corrupted upload; file saved with wrong encoding (UTF-16); JSON with trailing commas or comments; uploading a CSV renamed to .json.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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

Appendix: source

Thrown at label_studio/data_import/models.py:218

                    # Single JSON object: parse once and yield a single-item batch
                    raw_data = file_handle.read()
                    try:
                        task_data = json.loads(raw_data)
                    except TypeError:
                        task_data = json.loads(raw_data.decode('utf8'))
                    formatted_task = self._format_task_for_json_streaming(task_data)
                    batch.append(formatted_task)

                else:
                    # Unknown/invalid JSON structure
                    raise ValidationError('Unsupported or invalid JSON structure')

                # Yield remaining tasks if any
                if batch:
                    yield batch

        except Exception as exc:
            raise ValidationError(f'Failed to parse JSON file {self.file_name}: {extract_message(exc)}')

    def _format_task_for_json_streaming(self, task):
        """Format task data for JSON streaming consistency with read_tasks_list_from_json"""
        # Handle different task types as in the original read_tasks_list_from_json method
        if isinstance(task, dict):
            if not task.get('data'):
                task = {'data': task}
        else:
            # If task is not a dict (e.g., list), wrap it in {'data': task}
            task = {'data': task}

        if not isinstance(task['data'], dict):
            raise ValidationError('Task item should be dict')
        return task

    def read_task_from_hypertext_body(self):
        logger.debug('Read 1 task from hypertext file {}'.format(self.filepath))
        body = self.content

View on GitHub (pinned to 0b49e9b539)