HumanSignal/label-studio · error · ValidationError
Failed to parse JSON file {self.file_name}: {extract_message
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.
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.contentView on GitHub (pinned to 0b49e9b539)
Solutions
- Read the wrapped inner message after 'Failed to parse JSON file ...:' and fix the underlying JSON syntax issue
- Run the file through a JSON linter / python -m json.tool to locate the syntax error
- 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
- Always save as UTF-8 without BOM
- Run python -m json.tool on the file before upload
- Never rename CSV/TSV files to .json
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unsupported or invalid JSON structure
- Task item should be dict
- Failed to parse input file {self.file_name}: {extract_messag
- Error loading JSON from file "{key}".\nIf you're trying to i
- Your label config has more than one data key and direct file
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/0e69cab5636de324.
Report an issue: GitHub.